/// <summary> /// Adds <paramref name="numSamples"/> pieces of samples from the /// <paramref name="samples"/> memory position into the input of the /// object. Notice that sample rate _has_to_ be set before calling this /// function, otherwise throws a runtime_error exception. /// </summary> /// <param name="samples">Pointer to sample buffer.</param> /// <param name="numSamples">Number of samples in buffer. Notice that in /// case of stereo-sound a single sample contains data for both /// channels.</param> /// <exception cref="InvalidOperationException">Sample rate or number of /// channels not defined</exception> public override void PutSamples(ArrayPtr <TSampletype> samples, int numSamples) { if (!_isSampleRateSet) { throw new InvalidOperationException("SoundTouch : Sample rate not defined"); } if (_channels == 0) { throw new InvalidOperationException("SoundTouch : Number of channels not defined"); } // accumulate how many samples are expected out from processing, given the current // processing setting _samplesExpectedOut += (double)numSamples / ((double)_rate * (double)_tempo); #if !SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER if (_rate <= 1.0) { // transpose the rate down, output the transposed sound to tempo changer buffer Debug.Assert(Output == _stretch); _rateTransposer.PutSamples(samples, numSamples); _stretch.MoveSamples(_rateTransposer); } else #endif { // evaluate the tempo changer, then transpose the rate up, Debug.Assert(Output == _rateTransposer); _stretch.PutSamples(samples, numSamples); _rateTransposer.MoveSamples(_stretch); } }
/// <summary> /// Calculates effective rate & tempo values from /// <see cref="_virtualRate"/>, <see cref="_virtualTempo"/> and /// <see cref="_virtualPitch"/> parameters. /// </summary> private void CalcEffectiveRateAndTempo() { float oldTempo = _tempo; float oldRate = _rate; _tempo = _virtualTempo / _virtualPitch; _rate = _virtualPitch * _virtualRate; if (!TestFloatEqual(_rate, oldRate)) { _rateTransposer.SetRate(_rate); } if (!TestFloatEqual(_tempo, oldTempo)) { _stretch.SetTempo(_tempo); } #if !SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER if (_rate <= 1.0) { if (Output != _stretch) { Debug.Assert(Output == _rateTransposer); // move samples in the current output buffer to the output of pTDStretch var tempOut = _stretch.GetOutput(); tempOut.MoveSamples(Output); // move samples in pitch transposer's store buffer to tempo changer's input _stretch.MoveSamples(_rateTransposer.GetStore()); Output = _stretch; } } else #endif if (Output != _rateTransposer) { Debug.Assert(Output == _stretch); // move samples in the current output buffer to the output of pRateTransposer var transOut = _rateTransposer.GetOutput(); transOut.MoveSamples(Output); // move samples in tempo changer's input to pitch transposer's input _rateTransposer.MoveSamples(_stretch.GetInput()); Output = _rateTransposer; } }