Пример #1
0
		public void Write(Tag tag, Stream raf, Stream rafTemp) {
			//Read firstPage----------------------------------------------------
			raf.Seek(26, SeekOrigin.Begin);
			byte[] b = new byte[4];
			int pageSegments = raf.ReadByte()&0xFF; //Unsigned
			raf.Seek(0, SeekOrigin.Begin);

			b = new byte[27 + pageSegments];
			raf.Read(b, 0, b.Length);

			OggPageHeader firstPage = new OggPageHeader(b);
			//------------------------------------------------------------------

			raf.Seek(0, SeekOrigin.Begin);
			//write 1st page (unchanged)----------------------------------------
			byte[] pageBytes = new byte[firstPage.PageLength + 27 + pageSegments];
			raf.Read(pageBytes, 0, pageBytes.Length);
			rafTemp.Write(pageBytes, 0, pageBytes.Length);
			//rafTemp.Seek(firstPage.PageLength + raf.Position, SeekOrigin.Current);
			//------------------------------------------------------------------
			
			//Read 2nd page-----------------------------------------------------
			long pos = raf.Position;
			raf.Seek(raf.Position + 26, SeekOrigin.Begin);
			pageSegments = raf.ReadByte()&0xFF; //Unsigned
			raf.Seek(pos, SeekOrigin.Begin);
			
			b = new byte[27 + pageSegments];
			raf.Read(b, 0, b.Length);
			OggPageHeader secondPage = new OggPageHeader(b);
			long secondPageEndPos = raf.Position;
			//------------------------------------------------------------------

			//Compute old comment length----------------------------------------
			int oldCommentLength = 7; // [.vorbis]
			raf.Seek(raf.Position + 7, SeekOrigin.Begin);

			b = new byte[4];
			raf.Read(b, 0, b.Length);
			int vendorstringLength = Utils.GetNumber(b, 0,3);
			oldCommentLength += 4 + vendorstringLength;

			raf.Seek(raf.Position + vendorstringLength, SeekOrigin.Begin);

			b = new byte[4];
			raf.Read(b, 0, b.Length);
			int userComments = Utils.GetNumber(b, 0,3);
			oldCommentLength += 4;

			for (int i = 0; i < userComments; i++) {
				b = new byte[4];
				raf.Read(b, 0, b.Length);
				int commentLength = Utils.GetNumber(b, 0,3);
				oldCommentLength += 4 + commentLength;

				raf.Seek(raf.Position + commentLength, SeekOrigin.Begin);
			}

			int isValid = raf.ReadByte();
			oldCommentLength += 1;
			if (isValid != 1)
				throw new CannotWriteException("Unable to retreive old tag informations");
			//------------------------------------------------------------------

			//Get the new comment and create the container bytebuffer for 2nd page---
			ByteBuffer newComment = tc.Convert(tag);

			int newCommentLength = newComment.Capacity;
			int newSecondPageLength = secondPage.PageLength - oldCommentLength + newCommentLength;

			byte[] segmentTable = CreateSegmentTable(oldCommentLength,newCommentLength,secondPage);
			int newSecondPageHeaderLength = 27 + segmentTable.Length;

			ByteBuffer secondPageBuffer = new ByteBuffer(newSecondPageLength + newSecondPageHeaderLength);
			//------------------------------------------------------------------

			//Build the new second page header----------------------------------
			//OggS capture
			secondPageBuffer.Put(Utils.GetBytes("OggS"));
			//Stream struct revision
			secondPageBuffer.Put((byte) 0);
			//header_type_flag
			secondPageBuffer.Put((byte) 0);
			//absolute granule position
			secondPageBuffer.Put(
				new byte[] {
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0,
					(byte) 0 });

			//stream serial number
			secondPageBuffer.Put(Utils.GetNumber(secondPage.SerialNumber));

			//page sequence no
			secondPageBuffer.Put(Utils.GetNumber(secondPage.PageSequence));

			//CRC (to be computed later)
			secondPageBuffer.Put(new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0 });
			int crcOffset = 22;
			
			if (segmentTable.Length > 255) {
			    throw new CannotWriteException ("In this special case we need to " +
			    		"create a new page, since we still hadn't the time for that " +
			    		"we won't write because it wouldn't create an ogg file.");
			}
			//page_segments nb.
			secondPageBuffer.Put((byte)segmentTable.Length);

			//page segment table
			for (int i = 0; i < segmentTable.Length; i++)
				secondPageBuffer.Put(segmentTable[i]);
			//------------------------------------------------------------------

			//Add to the new second page the new comment------------------------
			secondPageBuffer.Put(newComment);
			//------------------------------------------------------------------

			//Add the remaining old second page (encoding infos, etc)-----------
			raf.Seek(secondPageEndPos+oldCommentLength, SeekOrigin.Begin);
			secondPageBuffer.Put(raf);
			//------------------------------------------------------------------

			//Compute CRC over the new second page------------------------------
			byte[] crc = OggCRCFactory.ComputeCRC(secondPageBuffer.Data);
			for (int i = 0; i < crc.Length; i++) {
				secondPageBuffer.Put(crcOffset + i, crc[i]);
			}
			//------------------------------------------------------------------

			//Transfer the second page bytebuffer content-----------------------
			secondPageBuffer.Rewind();
			rafTemp.Write(secondPageBuffer.Data, 0, secondPageBuffer.Data.Length);
			//------------------------------------------------------------------

			//Write the rest of the original file-------------------------------
			byte[] buf = new byte[65536];
			int read = raf.Read(buf, 0, buf.Length);
			while (read != 0) {
				rafTemp.Write(buf, 0, read);
				read = raf.Read(buf, 0, buf.Length);
			}
			//rafTemp.getChannel().transferFrom(raf.getChannel(), 	rafTemp.Position, raf.Length() - raf.Position);
			//------------------------------------------------------------------
		}
Пример #2
0
		public Tag Read( Stream raf ) {
			long oldPos = 0;
			//----------------------------------------------------------
			
			//Check wheter we have an ogg stream---------------
			raf.Seek( 0 , SeekOrigin.Begin);
			byte[] b = new byte[4];
			raf.Read(b, 0, b.Length);
			
			string ogg = new string(System.Text.Encoding.ASCII.GetChars(b));
			if( ogg != "OggS" )
				throw new CannotReadException("OggS Header could not be found, not an ogg stream");
			//--------------------------------------------------
			
			//Parse the tag ------------------------------------
			raf.Seek( 0 , SeekOrigin.Begin);

			//Supposing 1st page = codec infos
			//			2nd page = comment+decode info
			//...Extracting 2nd page
			
			//1st page to get the length
			b = new byte[4];
			oldPos = raf.Position;
			raf.Seek(26, SeekOrigin.Begin);
			int pageSegments = raf.ReadByte()&0xFF; //unsigned
			raf.Seek(oldPos, SeekOrigin.Begin);
			
			b = new byte[27 + pageSegments];
			raf.Read( b , 0,  b .Length);

			OggPageHeader pageHeader = new OggPageHeader( b );

			raf.Seek( raf.Position + pageHeader.PageLength , SeekOrigin.Begin);

			//2nd page extraction
			oldPos = raf.Position;
			raf.Seek(raf.Position + 26, SeekOrigin.Begin);
			pageSegments = raf.ReadByte()&0xFF; //unsigned
			raf.Seek(oldPos, SeekOrigin.Begin);
			
			b = new byte[27 + pageSegments];
			raf.Read( b , 0,  b .Length);
			pageHeader = new OggPageHeader( b );

			b = new byte[7];
			raf.Read( b , 0,  b .Length);
			
			string vorbis = new string(System.Text.Encoding.ASCII.GetChars(b, 1, 6));
			if(b[0] != 3 || vorbis != "vorbis")
				throw new CannotReadException("Cannot find comment block (no vorbis header)");

			//Begin tag reading
			OggTag tag = oggTagReader.Read(raf);
			
			byte isValid = (byte) raf.ReadByte();
			if ( isValid == 0 )
				throw new CannotReadException("Error: The OGG Stream isn't valid, could not extract the tag");
			
			return tag;
		}
Пример #3
0
	    /**
	     * This method creates a new segment table for the second page (header).
	     * @param oldCommentLength The lentgh of the old comment section, used to verify
	     * the old secment table
	     * @param newCommentLength Of this value the start of the segment table
	     * will be created.
	     * @param secondPage The second page from the source file.
	     * @return new segment table.
	     */
	    private byte[] CreateSegmentTable(int oldCommentLength, int newCommentLength, OggPageHeader secondPage)  {
	        int totalLenght = secondPage.PageLength;
	        byte[] restShouldBe = CreateSegments(totalLenght-oldCommentLength,false);
	        byte[] newStart = CreateSegments(newCommentLength,true);
	        byte[] result = new byte[newStart.Length+restShouldBe.Length];
	        newStart.CopyTo(result, 0);
	        restShouldBe.CopyTo(result, newStart.Length);
	        return result;
	    }
Пример #4
0
		public EncodingInfo Read( Stream raf )  {
			EncodingInfo info = new EncodingInfo();
			long oldPos = 0;
			
			//Reads the file encoding infos -----------------------------------
			raf.Seek( 0 , SeekOrigin.Begin);
			double PCMSamplesNumber = -1;
			raf.Seek( raf.Length-2, SeekOrigin.Begin);
			while(raf.Position >= 4) {
				if(raf.ReadByte()==0x53) {
					raf.Seek( raf.Position - 4, SeekOrigin.Begin);
					byte[] ogg = new byte[3];
					raf.Read(ogg, 0, 3);
					if(ogg[0]==0x4F && ogg[1]==0x67 && ogg[2]==0x67) {
						raf.Seek( raf.Position - 3, SeekOrigin.Begin);
						
						oldPos = raf.Position;
						raf.Seek(raf.Position + 26, SeekOrigin.Begin);
						int _pageSegments = raf.ReadByte()&0xFF; //Unsigned
						raf.Seek( oldPos , SeekOrigin.Begin);
						
						byte[] _b = new byte[27 + _pageSegments];
						raf.Read( _b, 0, _b.Length );

						OggPageHeader _pageHeader = new OggPageHeader( _b );
						raf.Seek(0, SeekOrigin.Begin);
						PCMSamplesNumber = _pageHeader.AbsoluteGranulePosition;
						break;
					}
				}	
				raf.Seek( raf.Position - 2, SeekOrigin.Begin);
			}
			
			if(PCMSamplesNumber == -1){
				throw new CannotReadException("Error: Could not find the Ogg Setup block");
			}
			

			//Supposing 1st page = codec infos
			//			2nd page = comment+decode info
			//...Extracting 1st page
			byte[] b = new byte[4];
			
			oldPos = raf.Position;
			raf.Seek(26, SeekOrigin.Begin);
			int pageSegments = raf.ReadByte()&0xFF; //Unsigned
			raf.Seek( oldPos , SeekOrigin.Begin);

			b = new byte[27 + pageSegments];
			raf.Read( b , 0,  b .Length);

			OggPageHeader pageHeader = new OggPageHeader( b );

			byte[] vorbisData = new byte[pageHeader.PageLength];

			raf.Read( vorbisData , 0,  vorbisData.Length);

			VorbisCodecHeader vorbisCodecHeader = new VorbisCodecHeader( vorbisData );

			//Populates encodingInfo----------------------------------------------------
			info.Duration = new TimeSpan((long)(PCMSamplesNumber / vorbisCodecHeader.SamplingRate) * TimeSpan.TicksPerSecond);
			info.ChannelNumber = vorbisCodecHeader.ChannelNumber;
			info.SamplingRate = vorbisCodecHeader.SamplingRate;
			info.EncodingType = vorbisCodecHeader.EncodingType;
			info.ExtraEncodingInfos = "";
			if(vorbisCodecHeader.NominalBitrate != 0
		        && vorbisCodecHeader.MaxBitrate == vorbisCodecHeader.NominalBitrate
		        && vorbisCodecHeader.MinBitrate == vorbisCodecHeader.NominalBitrate) {
			    //CBR
			    info.Bitrate = vorbisCodecHeader.NominalBitrate;
			    info.Vbr = false;
			}
			else if(vorbisCodecHeader.NominalBitrate != 0
			        && vorbisCodecHeader.MaxBitrate == 0
			        && vorbisCodecHeader.MinBitrate == 0) {
			    //Average vbr
			    info.Bitrate = vorbisCodecHeader.NominalBitrate;
			    info.Vbr = true;
			}
			else {
				info.Bitrate = ComputeBitrate( (int)info.Duration.TotalSeconds, raf.Length );
				info.Vbr = true;
			}

			return info;
		}
Пример #5
0
        public void Write(Tag tag, Stream raf, Stream rafTemp)
        {
            //Read firstPage----------------------------------------------------
            raf.Seek(26, SeekOrigin.Begin);
            byte[] b            = new byte[4];
            int    pageSegments = raf.ReadByte() & 0xFF;        //Unsigned

            raf.Seek(0, SeekOrigin.Begin);

            b = new byte[27 + pageSegments];
            raf.Read(b, 0, b.Length);

            OggPageHeader firstPage = new OggPageHeader(b);

            //------------------------------------------------------------------

            raf.Seek(0, SeekOrigin.Begin);
            //write 1st page (unchanged)----------------------------------------
            byte[] pageBytes = new byte[firstPage.PageLength + 27 + pageSegments];
            raf.Read(pageBytes, 0, pageBytes.Length);
            rafTemp.Write(pageBytes, 0, pageBytes.Length);
            //rafTemp.Seek(firstPage.PageLength + raf.Position, SeekOrigin.Current);
            //------------------------------------------------------------------

            //Read 2nd page-----------------------------------------------------
            long pos = raf.Position;

            raf.Seek(raf.Position + 26, SeekOrigin.Begin);
            pageSegments = raf.ReadByte() & 0xFF;           //Unsigned
            raf.Seek(pos, SeekOrigin.Begin);

            b = new byte[27 + pageSegments];
            raf.Read(b, 0, b.Length);
            OggPageHeader secondPage       = new OggPageHeader(b);
            long          secondPageEndPos = raf.Position;
            //------------------------------------------------------------------

            //Compute old comment length----------------------------------------
            int oldCommentLength = 7;             // [.vorbis]

            raf.Seek(raf.Position + 7, SeekOrigin.Begin);

            b = new byte[4];
            raf.Read(b, 0, b.Length);
            int vendorstringLength = Utils.GetNumber(b, 0, 3);

            oldCommentLength += 4 + vendorstringLength;

            raf.Seek(raf.Position + vendorstringLength, SeekOrigin.Begin);

            b = new byte[4];
            raf.Read(b, 0, b.Length);
            int userComments = Utils.GetNumber(b, 0, 3);

            oldCommentLength += 4;

            for (int i = 0; i < userComments; i++)
            {
                b = new byte[4];
                raf.Read(b, 0, b.Length);
                int commentLength = Utils.GetNumber(b, 0, 3);
                oldCommentLength += 4 + commentLength;

                raf.Seek(raf.Position + commentLength, SeekOrigin.Begin);
            }

            int isValid = raf.ReadByte();

            oldCommentLength += 1;
            if (isValid != 1)
            {
                throw new CannotWriteException("Unable to retreive old tag informations");
            }
            //------------------------------------------------------------------

            //Get the new comment and create the container bytebuffer for 2nd page---
            ByteBuffer newComment = tc.Convert(tag);

            int newCommentLength    = newComment.Capacity;
            int newSecondPageLength = secondPage.PageLength - oldCommentLength + newCommentLength;

            byte[] segmentTable = CreateSegmentTable(oldCommentLength, newCommentLength, secondPage);
            int    newSecondPageHeaderLength = 27 + segmentTable.Length;

            ByteBuffer secondPageBuffer = new ByteBuffer(newSecondPageLength + newSecondPageHeaderLength);

            //------------------------------------------------------------------

            //Build the new second page header----------------------------------
            //OggS capture
            secondPageBuffer.Put(Utils.GetBytes("OggS"));
            //Stream struct revision
            secondPageBuffer.Put((byte)0);
            //header_type_flag
            secondPageBuffer.Put((byte)0);
            //absolute granule position
            secondPageBuffer.Put(
                new byte[] {
                (byte)0,
                (byte)0,
                (byte)0,
                (byte)0,
                (byte)0,
                (byte)0,
                (byte)0,
                (byte)0
            });

            //stream serial number
            secondPageBuffer.Put(Utils.GetNumber(secondPage.SerialNumber));

            //page sequence no
            secondPageBuffer.Put(Utils.GetNumber(secondPage.PageSequence));

            //CRC (to be computed later)
            secondPageBuffer.Put(new byte[] { (byte)0, (byte)0, (byte)0, (byte)0 });
            int crcOffset = 22;

            if (segmentTable.Length > 255)
            {
                throw new CannotWriteException("In this special case we need to " +
                                               "create a new page, since we still hadn't the time for that " +
                                               "we won't write because it wouldn't create an ogg file.");
            }
            //page_segments nb.
            secondPageBuffer.Put((byte)segmentTable.Length);

            //page segment table
            for (int i = 0; i < segmentTable.Length; i++)
            {
                secondPageBuffer.Put(segmentTable[i]);
            }
            //------------------------------------------------------------------

            //Add to the new second page the new comment------------------------
            secondPageBuffer.Put(newComment);
            //------------------------------------------------------------------

            //Add the remaining old second page (encoding infos, etc)-----------
            raf.Seek(secondPageEndPos + oldCommentLength, SeekOrigin.Begin);
            secondPageBuffer.Put(raf);
            //------------------------------------------------------------------

            //Compute CRC over the new second page------------------------------
            byte[] crc = OggCRCFactory.ComputeCRC(secondPageBuffer.Data);
            for (int i = 0; i < crc.Length; i++)
            {
                secondPageBuffer.Put(crcOffset + i, crc[i]);
            }
            //------------------------------------------------------------------

            //Transfer the second page bytebuffer content-----------------------
            secondPageBuffer.Rewind();
            rafTemp.Write(secondPageBuffer.Data, 0, secondPageBuffer.Data.Length);
            //------------------------------------------------------------------

            //Write the rest of the original file-------------------------------
            byte[] buf  = new byte[65536];
            int    read = raf.Read(buf, 0, buf.Length);

            while (read != 0)
            {
                rafTemp.Write(buf, 0, read);
                read = raf.Read(buf, 0, buf.Length);
            }
            //rafTemp.getChannel().transferFrom(raf.getChannel(),   rafTemp.Position, raf.Length() - raf.Position);
            //------------------------------------------------------------------
        }
Пример #6
0
        /**
         * This method creates a new segment table for the second page (header).
         * @param oldCommentLength The lentgh of the old comment section, used to verify
         * the old secment table
         * @param newCommentLength Of this value the start of the segment table
         * will be created.
         * @param secondPage The second page from the source file.
         * @return new segment table.
         */
        private byte[] CreateSegmentTable(int oldCommentLength, int newCommentLength, OggPageHeader secondPage)
        {
            int totalLenght = secondPage.PageLength;

            byte[] restShouldBe = CreateSegments(totalLenght - oldCommentLength, false);
            byte[] newStart     = CreateSegments(newCommentLength, true);
            byte[] result       = new byte[newStart.Length + restShouldBe.Length];
            newStart.CopyTo(result, 0);
            restShouldBe.CopyTo(result, newStart.Length);
            return(result);
        }
Пример #7
0
        public Tag Read(Stream raf)
        {
            long oldPos = 0;

            //----------------------------------------------------------

            //Check wheter we have an ogg stream---------------
            raf.Seek(0, SeekOrigin.Begin);
            byte[] b = new byte[4];
            raf.Read(b, 0, b.Length);

            string ogg = new string(System.Text.Encoding.ASCII.GetChars(b));

            if (ogg != "OggS")
            {
                throw new CannotReadException("OggS Header could not be found, not an ogg stream");
            }
            //--------------------------------------------------

            //Parse the tag ------------------------------------
            raf.Seek(0, SeekOrigin.Begin);

            //Supposing 1st page = codec infos
            //			2nd page = comment+decode info
            //...Extracting 2nd page

            //1st page to get the length
            b      = new byte[4];
            oldPos = raf.Position;
            raf.Seek(26, SeekOrigin.Begin);
            int pageSegments = raf.ReadByte() & 0xFF;           //unsigned

            raf.Seek(oldPos, SeekOrigin.Begin);

            b = new byte[27 + pageSegments];
            raf.Read(b, 0, b.Length);

            OggPageHeader pageHeader = new OggPageHeader(b);

            raf.Seek(raf.Position + pageHeader.PageLength, SeekOrigin.Begin);

            //2nd page extraction
            oldPos = raf.Position;
            raf.Seek(raf.Position + 26, SeekOrigin.Begin);
            pageSegments = raf.ReadByte() & 0xFF;           //unsigned
            raf.Seek(oldPos, SeekOrigin.Begin);

            b = new byte[27 + pageSegments];
            raf.Read(b, 0, b.Length);
            pageHeader = new OggPageHeader(b);

            b = new byte[7];
            raf.Read(b, 0, b.Length);

            string vorbis = new string(System.Text.Encoding.ASCII.GetChars(b, 1, 6));

            if (b[0] != 3 || vorbis != "vorbis")
            {
                throw new CannotReadException("Cannot find comment block (no vorbis header)");
            }

            //Begin tag reading
            OggTag tag = oggTagReader.Read(raf);

            byte isValid = (byte)raf.ReadByte();

            if (isValid == 0)
            {
                throw new CannotReadException("Error: The OGG Stream isn't valid, could not extract the tag");
            }

            return(tag);
        }
Пример #8
0
        public EncodingInfo Read(Stream raf)
        {
            EncodingInfo info   = new EncodingInfo();
            long         oldPos = 0;

            //Reads the file encoding infos -----------------------------------
            raf.Seek(0, SeekOrigin.Begin);
            double PCMSamplesNumber = -1;

            raf.Seek(raf.Length - 2, SeekOrigin.Begin);
            while (raf.Position >= 4)
            {
                if (raf.ReadByte() == 0x53)
                {
                    raf.Seek(raf.Position - 4, SeekOrigin.Begin);
                    byte[] ogg = new byte[3];
                    raf.Read(ogg, 0, 3);
                    if (ogg[0] == 0x4F && ogg[1] == 0x67 && ogg[2] == 0x67)
                    {
                        raf.Seek(raf.Position - 3, SeekOrigin.Begin);

                        oldPos = raf.Position;
                        raf.Seek(raf.Position + 26, SeekOrigin.Begin);
                        int _pageSegments = raf.ReadByte() & 0xFF;                       //Unsigned
                        raf.Seek(oldPos, SeekOrigin.Begin);

                        byte[] _b = new byte[27 + _pageSegments];
                        raf.Read(_b, 0, _b.Length);

                        OggPageHeader _pageHeader = new OggPageHeader(_b);
                        raf.Seek(0, SeekOrigin.Begin);
                        PCMSamplesNumber = _pageHeader.AbsoluteGranulePosition;
                        break;
                    }
                }
                raf.Seek(raf.Position - 2, SeekOrigin.Begin);
            }

            if (PCMSamplesNumber == -1)
            {
                throw new CannotReadException("Error: Could not find the Ogg Setup block");
            }


            //Supposing 1st page = codec infos
            //			2nd page = comment+decode info
            //...Extracting 1st page
            byte[] b = new byte[4];

            oldPos = raf.Position;
            raf.Seek(26, SeekOrigin.Begin);
            int pageSegments = raf.ReadByte() & 0xFF;           //Unsigned

            raf.Seek(oldPos, SeekOrigin.Begin);

            b = new byte[27 + pageSegments];
            raf.Read(b, 0, b.Length);

            OggPageHeader pageHeader = new OggPageHeader(b);

            byte[] vorbisData = new byte[pageHeader.PageLength];

            raf.Read(vorbisData, 0, vorbisData.Length);

            VorbisCodecHeader vorbisCodecHeader = new VorbisCodecHeader(vorbisData);

            //Populates encodingInfo----------------------------------------------------
            info.Duration           = new TimeSpan((long)(PCMSamplesNumber / vorbisCodecHeader.SamplingRate) * TimeSpan.TicksPerSecond);
            info.ChannelNumber      = vorbisCodecHeader.ChannelNumber;
            info.SamplingRate       = vorbisCodecHeader.SamplingRate;
            info.EncodingType       = vorbisCodecHeader.EncodingType;
            info.ExtraEncodingInfos = "";
            if (vorbisCodecHeader.NominalBitrate != 0 &&
                vorbisCodecHeader.MaxBitrate == vorbisCodecHeader.NominalBitrate &&
                vorbisCodecHeader.MinBitrate == vorbisCodecHeader.NominalBitrate)
            {
                //CBR
                info.Bitrate = vorbisCodecHeader.NominalBitrate;
                info.Vbr     = false;
            }
            else if (vorbisCodecHeader.NominalBitrate != 0 &&
                     vorbisCodecHeader.MaxBitrate == 0 &&
                     vorbisCodecHeader.MinBitrate == 0)
            {
                //Average vbr
                info.Bitrate = vorbisCodecHeader.NominalBitrate;
                info.Vbr     = true;
            }
            else
            {
                info.Bitrate = ComputeBitrate((int)info.Duration.TotalSeconds, raf.Length);
                info.Vbr     = true;
            }

            return(info);
        }