protected override void RipLoop(Domain.BufferedStream bufferedStream) { _currentFrame = Mp3Frame.LoadFromStream(bufferedStream); if (_currentFrame == null) { throw new RipFailedException($"Failed to stream from '{CurrentStreamSource.StreamUrl}. The stream is either down or not a MP3 compatible stream."); } if (_decompressor == null) { // don't think these details matter too much - just help ACM select the right codec // however, the buffered provider doesn't know what sample rate it is working at // until we have a frame _waveFormat = new Mp3WaveFormat( _currentFrame.SampleRate, _currentFrame.ChannelMode == ChannelMode.Mono ? 1 : 2, _currentFrame.FrameLength, _currentFrame.BitRate ); _decompressor = new AcmMp3FrameDecompressor(_waveFormat); //var appSetting = AppSettings.Current; //if(appSetting.RecordBacktrackSeconds > 0) { // // ms per frame = (samples per frame / sample rate(in hz)) * 1000 // var backFrameStackSize = (appSetting.RecordBacktrackSeconds * 1000) / (((float)_currentFrame.SampleCount / (float)_currentFrame.SampleRate) * 1000); // BackFrames = new PipeQueue<FrameDecompressedEventArgs<Mp3Frame>>((int)Math.Ceiling(backFrameStackSize)); //} } int decompressed = _decompressor.DecompressFrame(_currentFrame, _buffer, 0); RaiseFrameDecompressed(_currentFrame, _waveFormat, _decompressor.OutputFormat, _buffer, decompressed); }
protected abstract void RipLoop(Domain.BufferedStream bufferedStream);
public void StartRip(StreamSource streamSource) { if (State != StreamRipperStates.Stopped) { throw new InvalidOperationException("The ripper is already running or not fully stopped yet."); } _worker = new BackgroundWorker(); _worker.RunWorkerCompleted += (sender, e) => { if (_streamEnded != null) { _streamEnded(e.Error); } }; _worker.DoWork += (sender, e) => { var req = (HttpWebRequest)HttpWebRequest.Create(streamSource.StreamUrl); HttpWebResponse resp; try { resp = (HttpWebResponse)req.GetResponse(); } catch (WebException ex) { if (ex.Status != WebExceptionStatus.RequestCanceled) { throw; } return; } try { _stopHandle = new EventWaitHandle(false, EventResetMode.ManualReset); State = StreamRipperStates.Running; CurrentStreamSource = streamSource; using (var responseStream = resp.GetResponseStream()) { var bufferedStream = new Domain.BufferedStream(responseStream); do { RipLoop(bufferedStream); if (_worker.CancellationPending) { e.Cancel = true; break; } } while(State == StreamRipperStates.Running); } } catch (EndOfStreamException) { // reached the end of the MP3 file / stream } catch (WebException) { // probably we have aborted download from the GUI thread } finally { RipLoopCleanup(); State = StreamRipperStates.Stopped; _stopHandle.Set(); } }; _worker.RunWorkerAsync(); }