/// <summary> /// Time stretching with auto-derived parameters /// </summary> /// <param name="signal">Signal</param> /// <param name="stretch">Stretch factor (ratio)</param> /// <param name="algorithm">Algorithm for TSM (optional)</param> /// <returns>Time stretched signal</returns> public static DiscreteSignal TimeStretch(DiscreteSignal signal, double stretch, TsmAlgorithm algorithm = TsmAlgorithm.PhaseVocoderPhaseLocking) { if (Math.Abs(stretch - 1.0) < 1e-10) { return(signal.Copy()); } IFilter stretchFilter; var frameSize = MathUtils.NextPowerOfTwo(1024 * signal.SamplingRate / 16000); switch (algorithm) { case TsmAlgorithm.PhaseVocoder: stretchFilter = new PhaseVocoder(stretch, frameSize / 10, frameSize); break; case TsmAlgorithm.PhaseVocoderPhaseLocking: stretchFilter = new PhaseLockingVocoder(stretch, frameSize / 8, frameSize); break; case TsmAlgorithm.PaulStetch: stretchFilter = new PaulStretch(stretch, frameSize / 10, frameSize * 4); break; default: stretchFilter = new Wsola(stretch); break; } return(stretchFilter.ApplyTo(signal, FilteringMethod.Auto)); }
/// <summary> /// Time stretching with parameters set by user /// </summary> /// <param name="signal">Signal</param> /// <param name="stretch">Stretch factor (ratio)</param> /// <param name="windowSize">Window size (for vocoders - FFT size)</param> /// <param name="hopSize">Hop size</param> /// <param name="algorithm">Algorithm for TSM (optional)</param> /// <returns>Time stretched signal</returns> public static DiscreteSignal TimeStretch(DiscreteSignal signal, double stretch, int windowSize, int hopSize, TsmAlgorithm algorithm = TsmAlgorithm.PhaseVocoderPhaseLocking) { if (Math.Abs(stretch - 1.0) < 1e-10) { return(signal.Copy()); } IFilter stretchFilter; switch (algorithm) { case TsmAlgorithm.PhaseVocoder: stretchFilter = new PhaseVocoder(stretch, hopSize, windowSize); break; case TsmAlgorithm.PhaseVocoderPhaseLocking: stretchFilter = new PhaseLockingVocoder(stretch, hopSize, windowSize); break; case TsmAlgorithm.PaulStetch: stretchFilter = new PaulStretch(stretch, hopSize, windowSize); break; default: stretchFilter = new Wsola(stretch, windowSize, hopSize); break; } return(stretchFilter.ApplyTo(signal, FilteringMethod.Auto)); }