Example #1
0
 /// <summary>
 /// copy construct AudioFrame for derived classes
 /// </summary>
 /// <param name="other"></param>
 protected AudioFrame(AudioFrame other)
 {
     _frameBuffer = other._frameBuffer;
     _header = other._header;
     _headerBytes = other._headerBytes;
 }
Example #2
0
        /// <summary>
        /// construct AudioFrame from a larger portion of the stream; don't rewind stream when done
        /// </summary>
        /// <param name="stream">source stream</param>
        /// <param name="header">parsed header</param>
        /// <param name="frameSize">size from header, or scanning for second frame of free bitrate file</param>
        /// <param name="remainingBytes">number of bytes in audio block, as reported by the caller</param>
        public AudioFrame(Stream stream, AudioFrameHeader header, uint frameSize, uint remainingBytes)
        {
            Debug.Assert(header != null);
            _header = header;

            _frameBuffer = new byte[frameSize];
            _headerBytes = _header.HeaderSize;

            int numgot = stream.Read(_frameBuffer, 0, (int)frameSize);
            if( numgot < (int)frameSize )
                throw new InvalidAudioFrameException(
                    string.Format("MPEG Audio AudioFrame: only {0} bytes of frame found when {1} bytes declared",
                                  numgot,
                                  frameSize));
        }
Example #3
0
        /// <summary>
        /// compare headers
        /// </summary>
        // return true if identical or related
        // return false if no similarities
        // (from an idea in CMPAHeader, http://www.codeproject.com/KB/audio-video/mpegaudioinfo.aspx)

        bool IsCompatible( AudioFrameHeader destHeader )
        {
	        // version change never possible
	        if (destHeader.RawMpegVersion != RawMpegVersion)
		        return false;

	        // layer change never possible
	        if (destHeader.RawLayer != RawLayer)
		        return false;

	        // sampling rate change never possible
	        if (destHeader.RawSampleFreq != RawSampleFreq)
		        return false;

	        // from mono to stereo never possible
	        if (destHeader.IsMono != IsMono)
		        return false;

	        if (destHeader.RawEmphasis != RawEmphasis)
		        return false;

	        return true;
        }
Example #4
0
 /// <summary>
 /// construct AudioFrame from supplied bytes
 /// </summary>
 /// <param name="frameBuffer"></param>
 /// <remarks>buffer is correct size, even for free bitrate files</remarks>
 public AudioFrame(byte[] frameBuffer)
 {
     // find and parse frame header, rewind stream to start, or throw.
     _header = new AudioFrameHeader(frameBuffer);
     _headerBytes = _header.HeaderSize;
     _frameBuffer = frameBuffer;
 }
Example #5
0
        /// <summary>
        /// Creates Header
        /// </summary>
        /// <remarks>
        /// n.b. doesn't rewind the stream to the start of the frame.
        /// If the caller wants to read the entire frame in one block, they'll have to rewind it themselves.
        /// </remarks>
        /// <param name="stream"></param>
        /// <param name="remainingBytes"></param>
        /// <returns>valid audio header, or null</returns>
        static AudioFrameHeader CreateHeader( Stream stream, uint remainingBytes )
        {
            // save the start of the skip operation, for error messages
            long streamStartpos = stream.Position;
            int framesSkipped = 0;

            // apply an upper limit of 64k to the number of bytes it will skip,
            // to prevent it trying to read the whole of a corrupt 5meg file
            // (MPAHeaderInfo skips 3 frames but I think it's worth checking further than that)
            if( remainingBytes > 65536 )
                remainingBytes = 65536;

            long endPos = streamStartpos + (long)remainingBytes;

            do
            {
                long remaining = endPos - (uint)stream.Position;
                int numskipped = Seek( stream, remaining );

                if( numskipped < 0 )
                {
                    //throw new InvalidAudioFrameException(
                    //    string.Format("MPEG Audio Frame: No header found from offset {0} to the end", streamStartpos));
                    return null;
                }
                //else if( numskipped > 0 )
                //    Trace.WriteLine( string.Format( "{0} bytes skipped to start of frame at offset {1}",
                //                                    numskipped, stream.Position - numskipped ) );

                // save the start of the real frame, i.e. after the rubbish is skipped
                long frameStartPos = stream.Position;

                AudioFrameHeader parsedHeader = new AudioFrameHeader( ReadHeader( stream ) );
                if( parsedHeader.Valid )
                {
                    if( frameStartPos > streamStartpos )
                    {
                        if( framesSkipped > 0 )
                            Trace.WriteLine(string.Format("total {0} bytes and {1} invalid frame headers skipped to get to the start of a valid frame at stream offset {2}",
                                                            frameStartPos - streamStartpos, framesSkipped, frameStartPos));
                        else
                            Trace.WriteLine(string.Format("total {0} bytes skipped to get to the start of a valid frame at stream offset {1}",
                                                            frameStartPos - streamStartpos, frameStartPos));
                    }
                    return parsedHeader;
                }

                // header is invalid mp3 frame, so skip a char and look again
                stream.Position = frameStartPos;
                ++framesSkipped;
                /*byte skipchar = (byte)*/stream.ReadByte();
                //Trace.WriteLine(string.Format("  Invalid MP3 frame; skipping 0x{0:X} at {1}", skipchar, frameStartPos + 1));
            }
            while( true );
        }