Beispiel #1
0
        /// <summary>
        /// Add invalid data (since we need to check garbage for a mp3 resync we may need to combine multiple invalid chunks).
        /// </summary>
        /// <param name="buffer">The buffer to add to invalid data frame.</param>
        void InvalidData(byte[] buffer)
        {
            if (buffer.Length == 0)
            {
                return;
            }

            if (m_InvalidFrame == null)
            {
                m_InvalidFrame = new MP3InvalidFrame();
            }
            m_InvalidFrame.Add(buffer);
        }
Beispiel #2
0
        /// <summary>
        /// Gets the next frame.
        /// </summary>
        /// <returns>Returns the next frame or null (at end of stream).</returns>
        public AudioFrame GetNextFrame()
        {
            while (true)
            {
                #region return buffered frames first (if any)
                // got a decoded frame at the cache ?
                if (m_BufferedFrame != null)
                {
                    AudioFrame result;
                    if (m_InvalidFrame != null)
                    {
                        result         = m_InvalidFrame;
                        m_InvalidFrame = null;
                    }
                    else
                    {
                        result          = m_BufferedFrame;
                        m_BufferedFrame = null;
                    }
                    return(result);
                }
                #endregion

                #region search next frame start

                // search the next interesting position
                var searchResult = FindFrame();
                if (searchResult == null)
                {
                    #region end of stream cleanup
                    // invalid data at end of stream ?
                    if (m_Reader.Available > 0)
                    {
                        // yes buffer
                        InvalidData(m_Reader.GetBuffer());
                    }

                    // got an invalid frame ?
                    if (m_InvalidFrame != null)
                    {
                        // return invalid frame
                        AudioFrame result = m_InvalidFrame;
                        m_InvalidFrame = null;
                        return(result);
                    }

                    // got an id3v1 ?
                    if (m_ID3v1 != null)
                    {
                        // return id3v1
                        AudioFrame result = m_ID3v1;
                        m_ID3v1 = null;
                        return(result);
                    }

                    // everything done, return null
                    return(null);

                    #endregion
                }
                #endregion

                #region check search result

                // got garbage at the beginning?
                if (searchResult.Index > 0)
                {
                    // yes, invalid data
                    InvalidData(m_Reader.GetBuffer(searchResult.Index));
                    continue;
                }
                #endregion

                #region decode frame

                // try to decode frame
                try
                {
                    var        valid = false;
                    AudioFrame frame = null;
                    switch (searchResult.Match)
                    {
                        #region decode mp3 frame
                    case MatchType.MP3Frame:
                        var audioFrame = new MP3AudioFrame();
                        valid = audioFrame.Parse(m_Reader);
                        frame = audioFrame;
                        break;
                        #endregion

                        #region decode id3 frame
                    case MatchType.ID3Frame:
                        frame = new ID3v2();
                        valid = frame.Parse(m_Reader);
                        break;
                        #endregion

                    default: throw new NotImplementedException(string.Format("Unknown frame type {0}", searchResult.Match));
                    }

                    // parsed successfully?
                    if (valid)
                    {
                        // yes, cache frame
                        m_BufferedFrame = frame;
                    }
                    else
                    {
                        // no invalidate
                        InvalidData(m_Reader.GetBuffer(1));
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(string.Format("Error while decoding {0} in stream {1}", searchResult.Match, m_Reader));
                    Trace.TraceError(ex.ToString());

                    // invalid frame or decoder error, move ahead
                    var count = (searchResult.Index < 0) ? 1 : searchResult.Index + 1;
                    InvalidData(m_Reader.GetBuffer(count));
                }
                #endregion
            }
        }