Skip to main content

A Velvet-Noise Decorrelator for audio

Project description

VNDecorrelate

VersionPyPITests

A Velvet-Noise Decorrelator for audio.

Decorrelation refers to the process of transforming an audio source signal into multiple output signals with different waveforms from each other, but with the same sound as the source signal [1].

In music production, decorrelation is typically applied to the left and right audio channels, creating the perception of stereo width and space. This, however, may come at the cost of potential coloration or transient smearing artifacts.

Velvet-Noise Decorrelation (VND) attempts to minimize these artifacts as well as computation cost while reducing the correlation of the outputs as much as possible [2].

Velvet Noise

Velvet Noise is a sparse noise sequence generated from randomly time-shifted impulses with a random value of either -1 or 1 [2]:

Basic Velvet Noise

To reduce transient smearing and frequency coloration you can apply a segmented decay envelope [2]:

Segmented Decaying Velvet Noise

As well as logarithmically distribute the impulses towards the start of the sequence [2]:

Segmented Decaying Log Distributed Velvet Noise

Quick Start

First install the package into your environment: pip install vndecorrelate

Then load an audio file.

import scipy.io.wavfile as wavfile
from vndecorrelate.decorrelation import *

fs, input_signal = wavfile.read("audio/viola.wav")

Then you can simply use the VelvetNoise class:

velvet_noise = VelvetNoise(
    sample_rate_hz=fs,
    duration_seconds=0.03,
    num_impulses=30,
)
output_signal = velvet_noise.decorrelate(input_signal)

Or:

# manually generate the velvet noise as numpy NDArrays
velvet_noise = generate_velvet_noise(
    duration_seconds=0.03,
    num_impulses=30,
)
# numerically equivalent to VelvetNoise.convolve
output_signal = convolve_velvet_noise(input_signal, velvet_noise)

Or you can create a chain of signal processors:

chain = (
    SignalChain(sample_rate_hz=fs)
    .velvet_noise(
        duration_seconds=0.03,
        num_impulses=30,
        log_distribution_strength=1.0,
        seed=1,
    )
    .haas_effect(
        delay_time_seconds=0.02,
        delayed_channel=1, # Right Channel
        mode='LR',
    )
)
# SignalChain is lazy, so instatiation of its signal processors happens here
output_signal = chain(input_signal)

To listen back to the processed audio, simply save to a wav file locally.

wavfile.write('audio/viola_out.wav', fs, output_signal)

Optimization

optimization.py contains functions for optimizing VelvetNoise or HaasEffect for maximizing stereo seperation while maintaining polar sample symmetry and mono compatiblilty.

optimize_velvet_noise optimizes the concentration of impulses towards the start of the filter referred to as log_distribution_strength:

Kappa

optimize_haas_delay optimizes the delay_time_seconds parameter:

Tau

symmetry_aware_objective takes the input signal and converts it to polar samples to compute the scalar objective function defined by:

Symmetry Aware Objective
where Alpha is the input scalar to optimize, each Moment is a moment of the polar sample distribution:
Weighted Angular Variance is the weighted angular variance
Centroid is the weighted mean (centroid)
Skewness is the skewness,
R is the correlation between the input left and right channels, Phi is the angle constraint threshold, and each Lambda is a penalty weight.

Sample runs of VelvetNoise.decorrelate with unoptimized and optimized filters can be compared by their polar sample plots generated from plot_polar_sample:

Unoptimized VN Vectorscope VN Optimized Vectorscope

Visualization

To provide further visualization of the effects decorrelation plot_correlogram is provided. Short windows of typically ~20ms are taken from two signals to calculate normalized cross-correlation values at various lag distances. sine_sweep can be used to generate a test signal that can be compared before and after applying a velvet noise decorrelation. Sine Sweep Signal We can use the auto correlogram as a baseline: Sine Sweep Auto Correlogram Plot the cross correlogram after filtering each channel with velvet noise: Velvet Noise Filtered Sine Sweep Cross Correlogram And compare to the behavior of filtering with white noise: White Noise Filtered Sine Sweep Cross Correlogram

References

[1] Sweetwater, “Decorrelation,” InSync, Dec. 17, 2004. https://www.sweetwater.com/insync/decorrelation/ (accessed May 15, 2026).

[2] B. Alary, A. Politis, and V. Välimäki, “VELVET-NOISE DECORRELATOR,” Proceedings of the 20th International Conference on Digital Audio Effects (DAFx-17), Edinburgh, UK, Sep. 2017. Accessed: May 15, 2026. [Online]. Available: http://www.dafx17.eca.ed.ac.uk/papers/DAFx17_paper_96.pdf

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vndecorrelate-1.0.6.tar.gz (17.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vndecorrelate-1.0.6-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file vndecorrelate-1.0.6.tar.gz.

File metadata

  • Download URL: vndecorrelate-1.0.6.tar.gz
  • Upload date:
  • Size: 17.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vndecorrelate-1.0.6.tar.gz
Algorithm Hash digest
SHA256 aab2a52b4ad29831333a39497bc2fa1ceb7d3acda5880cd97d407059303e2254
MD5 70ad5b50c4dd26f44ae27b06d877ef83
BLAKE2b-256 fcd5d9cd3821c7f0972c6f4d2fcccc979c56452c6f97f5a26f01089ad553ea48

See more details on using hashes here.

Provenance

The following attestation bundles were made for vndecorrelate-1.0.6.tar.gz:

Publisher: release.yaml on ckonst/VNDecorrelate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vndecorrelate-1.0.6-py3-none-any.whl.

File metadata

  • Download URL: vndecorrelate-1.0.6-py3-none-any.whl
  • Upload date:
  • Size: 20.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vndecorrelate-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 0b5120b4bd0337eecc32afd26bf578cf4c50caf88de0eb5d1fd2f71038f48df4
MD5 6b6c670a0233bba60c6ea53358f169e4
BLAKE2b-256 d60683f5257c69e9f2c20846b770dd218089cc97dcb15b6c396eb2bd72867873

See more details on using hashes here.

Provenance

The following attestation bundles were made for vndecorrelate-1.0.6-py3-none-any.whl:

Publisher: release.yaml on ckonst/VNDecorrelate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page