public int Read(float[] buffer, int offset, int count) { if (playbackRate == 0) // play silence { for (int n = 0; n < count; n++) { buffer[offset++] = 0; } return(count); } if (repositionRequested) { soundTouch.Clear(); repositionRequested = false; } int samplesRead = 0; bool reachedEndOfSource = false; while (samplesRead < count) { if (soundTouch.NumberOfSamplesAvailable == 0) { var readFromSource = sourceProvider.Read(sourceReadBuffer, 0, sourceReadBuffer.Length); if (readFromSource > 0) { soundTouch.PutSamples(sourceReadBuffer, readFromSource / channelCount); } else { reachedEndOfSource = true; // we've reached the end, tell SoundTouch we're done soundTouch.Flush(); } } var desiredSampleFrames = (count - samplesRead) / channelCount; var received = soundTouch.ReceiveSamples(soundTouchReadBuffer, desiredSampleFrames) * channelCount; // use loop instead of Array.Copy due to WaveBuffer for (int n = 0; n < received; n++) { buffer[offset + samplesRead++] = soundTouchReadBuffer[n]; } if (received == 0 && reachedEndOfSource) { break; } } if (reachedEndOfSource && !endNotified) { PlaybackEnded.Invoke(this, new StoppedEventArgs()); endNotified = true; } return(samplesRead); }
private void Process(SoundTouch <TSampleType, TLongSampleType> pSoundTouch, WavInFile inFile, WavOutFile outFile) { int nSamples; var sampleBuffer = new TSampleType[BUFF_SIZE]; if ((inFile == null) || (outFile == null)) { return; // nothing to do. } int nChannels = inFile.GetNumChannels(); int buffSizeSamples = BUFF_SIZE / nChannels; // Process samples read from the input file while (!inFile.Eof()) { // Read a chunk of samples from the input file int num = inFile.Read(sampleBuffer, BUFF_SIZE); nSamples = num / inFile.GetNumChannels(); // Feed the samples into SoundTouch processor pSoundTouch.PutSamples(sampleBuffer, nSamples); do { nSamples = pSoundTouch.ReceiveSamples(sampleBuffer, buffSizeSamples); outFile.Write(sampleBuffer, nSamples * nChannels); } while (nSamples != 0); } // Now the input file is processed, yet 'flush' few last samples that are // hiding in the SoundTouch's internal processing pipeline. pSoundTouch.Flush(); do { nSamples = pSoundTouch.ReceiveSamples(sampleBuffer, buffSizeSamples); outFile.Write(sampleBuffer, nSamples * nChannels); } while (nSamples != 0); }