Example #1
0
		/// <summary>
		/// Opens MP3 from a stream rather than a file
		/// Will not dispose of this stream itself
		/// </summary>
		/// <param name="inputStream"></param>
		public Mp3FileReader(Stream inputStream)
		{
			// Calculated as a double to minimize rounding errors
			double bitRate;

			mp3Stream = inputStream;
			id3v2Tag = Id3v2Tag.ReadTag(mp3Stream);

			dataStartPosition = mp3Stream.Position;
			var mp3Frame = new Mp3Frame(mp3Stream);
			sampleRate = mp3Frame.SampleRate;
			frameLengthInBytes = mp3Frame.FrameLength;
			bitRate = mp3Frame.BitRate;
			xingHeader = XingHeader.LoadXingHeader(mp3Frame);
			// If the header exists, we can skip over it when decoding the rest of the file
			if (xingHeader != null) dataStartPosition = mp3Stream.Position;

			mp3DataLength = mp3Stream.Length - dataStartPosition;

			// try for an ID3v1 tag as well
			mp3Stream.Position = mp3Stream.Length - 128;
			var tag = new byte[128];
			mp3Stream.Read(tag, 0, 3);
			if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'G')
			{
				id3v1Tag = tag;
				mp3DataLength -= 128;
			}

			mp3Stream.Position = dataStartPosition;

			CreateTableOfContents();
			tocIndex = 0;

			// [Bit rate in Kilobits/sec] = [Length in kbits] / [time in seconds] 
			//                            = [Length in bits ] / [time in milliseconds]

			// Note: in audio, 1 kilobit = 1000 bits.
			bitRate = (mp3DataLength*8.0/TotalSeconds());

			mp3Stream.Position = dataStartPosition;

			Mp3WaveFormat = new Mp3WaveFormat(sampleRate, mp3Frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frameLengthInBytes,
			                                  (int) bitRate);
			decompressor = new AcmMp3FrameDecompressor(Mp3WaveFormat); // new DmoMp3FrameDecompressor(this.Mp3WaveFormat); 
			waveFormat = decompressor.OutputFormat;
			bytesPerSample = (decompressor.OutputFormat.BitsPerSample)/8*decompressor.OutputFormat.Channels;
			// no MP3 frames have more than 1152 samples in them
			// some MP3s I seem to get double
			decompressBuffer = new byte[1152*bytesPerSample*2];
		}
Example #2
0
        /// <summary>
        /// Load Xing Header
        /// </summary>
        /// <param name="frame">Frame</param>
        /// <returns>Xing Header</returns>
        public static XingHeader LoadXingHeader(Mp3Frame frame)
        {
            var xingHeader = new XingHeader();

            xingHeader.frame = frame;
            int offset = 0;

            if (frame.MpegVersion == MpegVersion.Version1)
            {
                if (frame.ChannelMode != ChannelMode.Mono)
                {
                    offset = 32 + 4;
                }
                else
                {
                    offset = 17 + 4;
                }
            }
            else if (frame.MpegVersion == MpegVersion.Version2)
            {
                if (frame.ChannelMode != ChannelMode.Mono)
                {
                    offset = 17 + 4;
                }
                else
                {
                    offset = 9 + 4;
                }
            }
            else
            {
                return(null);
                // throw new FormatException("Unsupported MPEG Version");
            }

            if ((frame.RawData[offset + 0] == 'X') &&
                (frame.RawData[offset + 1] == 'i') &&
                (frame.RawData[offset + 2] == 'n') &&
                (frame.RawData[offset + 3] == 'g'))
            {
                xingHeader.startOffset = offset;
                offset += 4;
            }
            else
            {
                return(null);
            }

            var flags = (XingHeaderOptions)ReadBigEndian(frame.RawData, offset);

            offset += 4;

            if ((flags & XingHeaderOptions.Frames) != 0)
            {
                xingHeader.framesOffset = offset;
                offset += 4;
            }
            if ((flags & XingHeaderOptions.Bytes) != 0)
            {
                xingHeader.bytesOffset = offset;
                offset += 4;
            }
            if ((flags & XingHeaderOptions.Toc) != 0)
            {
                xingHeader.tocOffset = offset;
                offset += 100;
            }
            if ((flags & XingHeaderOptions.VbrScale) != 0)
            {
                xingHeader.vbrScale = ReadBigEndian(frame.RawData, offset);
                offset += 4;
            }
            xingHeader.endOffset = offset;
            return(xingHeader);
        }
Example #3
0
		/// <summary>
		/// Load Xing Header
		/// </summary>
		/// <param name="frame">Frame</param>
		/// <returns>Xing Header</returns>
		public static XingHeader LoadXingHeader(Mp3Frame frame)
		{
			var xingHeader = new XingHeader();
			xingHeader.frame = frame;
			int offset = 0;

			if (frame.MpegVersion == MpegVersion.Version1)
			{
				if (frame.ChannelMode != ChannelMode.Mono)
					offset = 32 + 4;
				else
					offset = 17 + 4;
			}
			else if (frame.MpegVersion == MpegVersion.Version2)
			{
				if (frame.ChannelMode != ChannelMode.Mono)
					offset = 17 + 4;
				else
					offset = 9 + 4;
			}
			else
			{
				return null;
				// throw new FormatException("Unsupported MPEG Version");
			}

			if ((frame.RawData[offset + 0] == 'X') &&
			    (frame.RawData[offset + 1] == 'i') &&
			    (frame.RawData[offset + 2] == 'n') &&
			    (frame.RawData[offset + 3] == 'g'))
			{
				xingHeader.startOffset = offset;
				offset += 4;
			}
			else
			{
				return null;
			}

			var flags = (XingHeaderOptions) ReadBigEndian(frame.RawData, offset);
			offset += 4;

			if ((flags & XingHeaderOptions.Frames) != 0)
			{
				xingHeader.framesOffset = offset;
				offset += 4;
			}
			if ((flags & XingHeaderOptions.Bytes) != 0)
			{
				xingHeader.bytesOffset = offset;
				offset += 4;
			}
			if ((flags & XingHeaderOptions.Toc) != 0)
			{
				xingHeader.tocOffset = offset;
				offset += 100;
			}
			if ((flags & XingHeaderOptions.VbrScale) != 0)
			{
				xingHeader.vbrScale = ReadBigEndian(frame.RawData, offset);
				offset += 4;
			}
			xingHeader.endOffset = offset;
			return xingHeader;
		}