Time-stretch the noise component of a sound by morphing, not by phase-vocoder propagation. More...
#include <pulp/signal/checked_allocation.hpp>#include <algorithm>#include <cmath>#include <cstddef>#include <cstdint>#include <complex>#include <vector>Go to the source code of this file.
Classes | |
| class | pulp::signal::NoiseMorpherT< SampleType > |
| RT contract: prepare() and prepare_masked_scratch() allocate storage and must run off the audio thread. More... | |
Namespaces | |
| namespace | pulp |
| namespace | pulp::signal |
Typedefs | |
| using | pulp::signal::NoiseMorpher = NoiseMorpherT<float> |
| using | pulp::signal::NoiseMorpher64 = NoiseMorpherT<double> |
Time-stretch the noise component of a sound by morphing, not by phase-vocoder propagation.
A phase vocoder cannot stretch noise correctly: moving analysis frames distorts the temporal correlation of the STFT coefficients, and phase propagation cannot restore a noise signal's statistics, so stretched noise sounds "tonalized" / phasey (Liao & Röbel, "On Stretching Gaussian Noises with the Phase Vocoder," DAFx 2012). The fix is to regenerate the noise from a fresh white-noise excitation shaped by the time-interpolated noise magnitude envelope, so every synthesis frame is decorrelated from its neighbours while preserving the spectral shape (Moliner, Fierro, Wright, Hämäläinen & Välimäki, "Noise Morphing for Audio Time Stretching," 2023).
This primitive produces, per synthesis frame, a complex spectrum whose magnitude is the (interpolated) noise envelope and whose phase is fresh random — a magnitude-locked white-noise excitation. Fed through SpectralFrameEngine's overlap-add synthesis, successive random-phase frames sum to decorrelated noise of the right color, stretching transparently at any ratio. Deterministic (seeded xorshift); no allocation after prepare().