public MpegFrameHeader ReadFrameHeader() { byte[] header = new byte[10]; long frameStart = _input.Position; while (header[0] != 0xFF) { frameStart = _input.Position; int value = _input.ReadByte(); if (value == -1) { return(null); } header[0] = (byte)value; } _input.Read(header, 1, 9); _input.Seek(frameStart, SeekOrigin.Begin); MpegFrameHeader result = new MpegFrameHeader(); if (!ParseMpegFrameHeader(result, header)) { throw new BinaryAssetBuilderException(ErrorCode.InvalidArgument, "Could not parse MP3 frame header."); } _input.Seek(result.HeaderSize, SeekOrigin.Current); return(result); }
private bool ParseMpegFrameHeader(MpegFrameHeader mpegFrameHeader, byte[] header) { BitStream bitStream = new BitStream(header); if (bitStream.ReadUInt16(11) != 0x07FFu) { throw new BinaryAssetBuilderException(ErrorCode.InternalError, "MP3 sync bits do not match."); } mpegFrameHeader.Version = (MpegVersion)bitStream.ReadByte(2); if (bitStream.ReadByte(2) != 0x01u) { throw new BinaryAssetBuilderException(ErrorCode.InternalError, "MP3 frame header error."); } mpegFrameHeader.HasCrc = bitStream.ReadBit(); mpegFrameHeader.BitrateIndex = bitStream.ReadByte(4); mpegFrameHeader.SampleRateIndex = bitStream.ReadByte(2); mpegFrameHeader.HasPadding = bitStream.ReadBit(); bitStream.ReadBit(); mpegFrameHeader.ChannelMode = (MpegChannelType)bitStream.ReadByte(2); mpegFrameHeader.ModeExtension = bitStream.ReadByte(2); mpegFrameHeader.HeaderSize = 4 + (mpegFrameHeader.HasCrc ? 2 : 0); mpegFrameHeader.SampleRate = _sampleRateTable[(int)mpegFrameHeader.Version, mpegFrameHeader.SampleRateIndex]; switch (mpegFrameHeader.Version) { case MpegVersion.V1: mpegFrameHeader.FrameSize = 144000 * _bitrateTable[(int)mpegFrameHeader.Version, mpegFrameHeader.BitrateIndex] / mpegFrameHeader.SampleRate; break; case MpegVersion.V2: case MpegVersion.V2_5: mpegFrameHeader.FrameSize = 144000 * _bitrateTable[(int)mpegFrameHeader.Version, mpegFrameHeader.BitrateIndex] / (mpegFrameHeader.SampleRate / 2); break; default: throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Bad MP3 version."); } if (mpegFrameHeader.HasPadding) { ++mpegFrameHeader.FrameSize; } mpegFrameHeader.NumberOfChannels = mpegFrameHeader.ChannelMode == MpegChannelType.Mono ? 1 : 2; return(true); }
public MpegConverterSettings GetSettings() { MpegConverterSettings result = new MpegConverterSettings(); // at the moment we ignore everything but IsStreamed & channels anyway, we assume channels are same for every mp3 header byte[] header = new byte[10]; long frameStart = _input.Position; _input.Read(header, 0, 10); _input.Seek(frameStart, SeekOrigin.Begin); if (header[0] == 'I' && header[1] == 'D' && header[2] == '3') { SkipID3Tag(header); } while (header[0] != 0xFF) { frameStart = _input.Position; int value = _input.ReadByte(); if (value == -1) { throw new BinaryAssetBuilderException(ErrorCode.InvalidArgument, "Could not find MP3 frame header."); } header[0] = (byte)value; } _input.Read(header, 1, 9); _input.Seek(frameStart, SeekOrigin.Begin); MpegFrameHeader frameHeader = new MpegFrameHeader(); if (!ParseMpegFrameHeader(frameHeader, header)) { throw new BinaryAssetBuilderException(ErrorCode.InvalidArgument, "Could not parse MP3 frame header."); } result.NumberOfChannels = frameHeader.NumberOfChannels; result.SampleRate = frameHeader.SampleRate; return(result); }