示例#1
0
        public void Read(T[] outBuf, int outChannels, int outSampleRate)
        {
            lock (this)
            {
                if (this.started)
                {
                    int outPos = 0;
                    // enough data in remaining frames to fill entire out buffer
                    // framesElemRem / this.sampleRate >= outElemRem / outSampleRate
                    while ((this.frameQueue.Count * this.frameSamples - this.curPlayingFrameSamplePos) * this.channels * outSampleRate >= (outBuf.Length - outPos) * this.sampleRate)
                    {
                        int playingFramePos = this.curPlayingFrameSamplePos * this.channels;
                        var frame           = frameQueue.Peek();
                        int outElemRem      = outBuf.Length - outPos;
                        int frameElemRem    = frame.Length - playingFramePos;

                        // enough data in the current frame to fill entire out buffer and some will remain for the next call: keeping this frame
                        // frameElemRem / (frCh * frRate) > outElemRem / (outCh * outRate)
                        if (frameElemRem * outChannels * outSampleRate > outElemRem * this.channels * this.sampleRate)
                        {
                            // frame remainder is large enough to fill outBuf remainder, keep this frame and return
                            //int framePosDelta = this.channels * outChannels * this.sampleRate / (outElemRem * outSampleRate);
                            int framePosDelta = outElemRem * this.channels * this.sampleRate / (outChannels * outSampleRate);
                            if (this.sampleRate == outSampleRate && this.channels == outChannels)
                            {
                                System.Buffer.BlockCopy(frame, playingFramePos * elementSize, outBuf, outPos * elementSize, outElemRem * elementSize);
                            }
                            else
                            {
                                AudioUtil.Resample(frame, playingFramePos, framePosDelta, this.channels, outBuf, outPos, outElemRem, outChannels);
                            }
                            this.curPlayingFrameSamplePos += framePosDelta / this.channels;

                            return;
                        }
                        // discarding current frame because it fills exactly out buffer or next frame required to do so
                        else
                        {
                            int outPosDelta = frameElemRem * outChannels * outSampleRate / (this.channels * this.sampleRate);
                            if (this.sampleRate == outSampleRate && this.channels == outChannels)
                            {
                                System.Buffer.BlockCopy(frame, playingFramePos * elementSize, outBuf, outPos * elementSize, frameElemRem * elementSize);
                            }
                            else
                            {
                                AudioUtil.Resample(frame, playingFramePos, frameElemRem, this.channels, outBuf, outPos, outPosDelta, outChannels);
                            }
                            outPos += outPosDelta;

                            this.curPlayingFrameSamplePos = 0;

                            dequeueFrameQueue();

                            if (outPosDelta == outElemRem)
                            {
                                return;
                            }
                        }
                    }
                }
            }
        }
示例#2
0
 public T[] Process(T[] buf)
 {
     AudioUtil.Resample(buf, this.frameResampled, this.frameResampled.Length, channels);
     return(this.frameResampled);
 }