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);
        }
Exemple #2
0
 protected abstract void RipLoop(Domain.BufferedStream bufferedStream);
Exemple #3
0
        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();
        }