/// <summary>Begins the decoding process.</summary> /// <param name="source">The source.</param> /// <exception cref="NotSupportedException">Only Layer 3 Audio is supported!.</exception> /// <exception cref="Exception">Decoding already started!.</exception> public override void BeginDecode(IFrameSource source) { if (m_FrameDecoder != null) { Close(); } SourceName = source.Name; m_Source = source; // get first audio frame MP3AudioFrame l_MP3Frame = ReadNextAudioFrame(); if (l_MP3Frame.Header.Layer != MP3AudioFrameLayer.Layer3) { throw new NotSupportedException("Source " + SourceName + ": Only Layer 3 Audio is supported!"); } // prepare decoder m_OutputChannels = l_MP3Frame.Header.ChannelCount; float[] isEqualizerFactors = m_Equalizer.GetFactors(); m_Filter1 = new MP3AudioSynthesisFilter(0, 32000.0f, isEqualizerFactors); if (m_OutputChannels == 2) { m_Filter2 = new MP3AudioSynthesisFilter(1, 32000.0f, isEqualizerFactors); } m_SamplingRate = l_MP3Frame.Header.SamplingRate; m_OutputBuffer = new MP3AudioStereoBuffer(m_SamplingRate); m_FrameDecoder = new MP3AudioLayerIIIDecoder(l_MP3Frame.Header, m_Filter1, m_Filter2, m_OutputBuffer, (int)MP3AudioOutputMode.Both); DecodeFrame(l_MP3Frame); }
/// <summary> /// Reads a frame from the MP3 stream. /// Returns whether the operation was successful. /// </summary> bool DecodeFrame(MP3AudioFrame frame) { if (frame == null) { return(false); } try { m_OutputBuffer.Clear(); m_FrameDecoder.DecodeFrame(frame); m_Resetted = false; return(true); } catch (Exception ex) { if (!m_Resetted) { m_FrameDecoder.Reset(); m_Resetted = true; } Trace.WriteLine("Source " + SourceName + ": Error while decoding mp3 frame.\n" + ex); return(false); } }
/// <summary>Reads the next audio frame and silently skips garbage and invalid frames.</summary> /// <returns></returns> MP3AudioFrame ReadNextAudioFrame() { MP3AudioFrame l_MP3Frame = null; while (l_MP3Frame == null) { AudioFrame frame = m_Source.GetNextFrame(); // eof ? if (frame == null) { return(null); } OnDecoding(frame); l_MP3Frame = frame as MP3AudioFrame; } return(l_MP3Frame); }
/// <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 } }