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; } } } } } }
public T[] Process(T[] buf) { AudioUtil.Resample(buf, this.frameResampled, this.frameResampled.Length, channels); return(this.frameResampled); }