vndecorrelate 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: vndecorrelate
3
+ Version: 1.0.0
4
+ Summary: A Velvet-Noise Decorrelator for audio
5
+ Author-email: Christian Konstantinov <ckonst98@gmail.com>
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: matplotlib>=3.10.3
10
+ Requires-Dist: numpy>=2.3.1
11
+ Requires-Dist: pillow==12.2.0
12
+ Requires-Dist: scipy>=1.16.0
13
+ Dynamic: license-file
14
+
15
+ # VNDecorrelate
16
+ ![Version](https://img.shields.io/badge/version-1.0.0-blue?style=for-the-badge)[![PyPI](https://img.shields.io/pypi/pyversions/vndecorrelate?style=for-the-badge)](https://pypi.org/project/vndecorrelate)![Tests](https://img.shields.io/github/actions/workflow/status/ckonst/VNDecorrelate/test-vnd.yaml?style=for-the-badge)
17
+
18
+ A Velvet-Noise Decorrelator for audio.
19
+
20
+ 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]](#1).
21
+
22
+ 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.
23
+
24
+ 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]](#2).
25
+
26
+ ## Velvet Noise
27
+
28
+ Velvet Noise is a sparse noise sequence generated from randomly time-shifted impulses with a random value of either -1 or 1 [[2]](#2):
29
+
30
+ ![Basic Velvet Noise](tests/plots/Basic%20Velvet%20Noise%20Sequence.png)
31
+
32
+ To reduce transient smearing and frequency coloration you can apply a segmented decay envelope [[2]](#2):
33
+
34
+ ![Segmented Decaying Velvet Noise](tests/plots/Segmented%20Decaying%20Velvet%20Noise%20Sequence.png)
35
+
36
+ As well as logarithmically distributing the impulses towards the start of the sequence [[2]](#2):
37
+
38
+ ![Segmented Decaying Log Distributed Velvet Noise](tests/plots/Segmented%20Decaying%20Log%20Distributed%20Velvet%20Noise%20Sequence.png)
39
+
40
+ ## Quick Start
41
+
42
+ First install the package into your environment:
43
+ ```pip install vndecorrelate```
44
+
45
+ Then load an audio file.
46
+
47
+ ```python
48
+ import scipy.io.wavfile as wavfile
49
+ from vndecorrelate.decorrelation import *
50
+
51
+ fs, input_signal = wavfile.read("audio/viola.wav")
52
+ ```
53
+
54
+ Then you can simply use the `VelvetNoise` class:
55
+
56
+ ```python
57
+ velvet_noise = VelvetNoise(
58
+ duration_seconds=0.03,
59
+ num_impulses=30,
60
+ )
61
+ output_signal = velvet_noise.decorrelate(input_signal)
62
+ ```
63
+ Or:
64
+
65
+ ```python
66
+ # manually generate the velvet noise as numpy NDArrays
67
+ velvet_noise = generate_velvet_noise(
68
+ duration_seconds=0.03,
69
+ num_impulses=30,
70
+ )
71
+ # numerically equivalent to VelvetNoise.convolve
72
+ output_signal = convolve_velvet_noise(input_signal, velvet_noise)
73
+ ```
74
+
75
+ Or you can create a chain of signal processors:
76
+
77
+ ```python
78
+ chain = (
79
+ SignalChain(sample_rate_hz=fs)
80
+ .velvet_noise(
81
+ duration_seconds=0.03,
82
+ num_impulses=30,
83
+ log_distribution_strength=1.0,
84
+ seed=1,
85
+ )
86
+ .haas_effect(
87
+ delay_time_seconds=0.02,
88
+ delayed_channel=1, # Right Channel
89
+ mode='LR',
90
+ )
91
+ )
92
+ # SignalChain is lazy, so instatiation of its signal processors happens here
93
+ output_signal = chain(input_signal)
94
+ ```
95
+ To listen back to the processed audio, simply save to a wav file locally.
96
+
97
+ ```python
98
+ wavfile.write('audio/viola_out.wav', fs, output_signal)
99
+ ```
100
+
101
+ ## Optimization
102
+ `optimization.py` contains functions for optimizing `VelvetNoise` or `HaasEffect` for maximizing stereo seperation while maintaining polar sample symmetry and mono compatiblilty.
103
+
104
+ `optimize_velvet_noise` optimizes the concentration of impulses towards the start of the filter: $\kappa \in [0.0, 1.0]$, referred to as `log_distribution_strength`.
105
+
106
+ `optimize_haas_delay` optimizes the `delay_time_seconds` parameter: $\tau \in [0.0, \text{max\\_delay\\_seconds}]$
107
+
108
+ `symmetry_aware_objective` takes the input signal and converts it to polar samples to compute the scalar objective function defined by:
109
+
110
+ $f(\alpha) = E_w[\theta^2] - \lambda_1(E_w[\theta])^2 - \lambda_2(E_w[\theta^3])^2 - \lambda_3r^2 - \lambda_4(max|{\theta}| - \phi)^2$
111
+
112
+ where $\alpha$ is the input scalar to optimize, each $E_w[\theta^n]$ is a moment of the polar sample distribution: $E_w[\theta^2]$ is the weighted angular variance, $(E_w[\theta])^2$ is the weighted mean (centroid), and $(E_w[\theta^3])^2$ is the skewness. $r$ is the correlation between the input left and right channels, $\phi$ is the `angle_limit` parameter, and each $\lambda_n$ is a penalty weight.
113
+
114
+ Sample runs of `VelvetNoise.decorrelate` with unoptimized and optimized filters can be compared by their polar sample plots generated from `plot_polar_sample`:
115
+
116
+ ![Unoptimized VN Vectorscope](tests/plots/Unoptimized%20VN%20Vectorscope.png)
117
+ ![VN Optimized Vectorscope](tests/plots/VN%20Optimized%20Vectorscope.png)
118
+
119
+ ## Visualization
120
+ 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.
121
+ ![Sine Sweep Signal](tests/plots/Sine%20Sweep%20Signal.png)
122
+ We can use the auto correlogram as a baseline:
123
+ ![Sine Sweep Auto Correlogram](tests/plots/Sine%20Sweep%20Auto%20Correlogram.png)
124
+ Plot the cross correlogram after filtering each channel with velvet noise:
125
+ ![Velvet Noise Filtered Sine Sweep Cross Correlogram](tests/plots/Velvet%20Noise%20Filtered%20Sine%20Sweep%20Cross%20Correlogram.png)
126
+ And compare to the behavior of filtering with white noise:
127
+ ![White Noise Filtered Sine Sweep Cross Correlogram](tests/plots/White%20Noise%20Filtered%20Sine%20Sweep%20Cross%20Correlogram.png)
128
+
129
+ ## References
130
+ <a id="1"> </a>
131
+ [1] “What is ‘Decorrelation’? | Sweetwater”. <a
132
+ href="https://www.sweetwater.com/insync/decorrelation/">
133
+ https://www.sweetwater.com/insync/decorrelation/</a> (accessed Aug. 10, 2020).
134
+
135
+ <a id="2"> </a>
136
+ [2] “Velvet-Noise Decorrelator”. <a
137
+ href="http://www.dafx17.eca.ed.ac.uk/papers/DAFx17_paper_96.pdf">
138
+ http://www.dafx17.eca.ed.ac.uk/papers/DAFx17_paper_96.pdf</a> (accessed Aug. 04, 2020).
@@ -0,0 +1,124 @@
1
+ # VNDecorrelate
2
+ ![Version](https://img.shields.io/badge/version-1.0.0-blue?style=for-the-badge)[![PyPI](https://img.shields.io/pypi/pyversions/vndecorrelate?style=for-the-badge)](https://pypi.org/project/vndecorrelate)![Tests](https://img.shields.io/github/actions/workflow/status/ckonst/VNDecorrelate/test-vnd.yaml?style=for-the-badge)
3
+
4
+ A Velvet-Noise Decorrelator for audio.
5
+
6
+ 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]](#1).
7
+
8
+ 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.
9
+
10
+ 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]](#2).
11
+
12
+ ## Velvet Noise
13
+
14
+ Velvet Noise is a sparse noise sequence generated from randomly time-shifted impulses with a random value of either -1 or 1 [[2]](#2):
15
+
16
+ ![Basic Velvet Noise](tests/plots/Basic%20Velvet%20Noise%20Sequence.png)
17
+
18
+ To reduce transient smearing and frequency coloration you can apply a segmented decay envelope [[2]](#2):
19
+
20
+ ![Segmented Decaying Velvet Noise](tests/plots/Segmented%20Decaying%20Velvet%20Noise%20Sequence.png)
21
+
22
+ As well as logarithmically distributing the impulses towards the start of the sequence [[2]](#2):
23
+
24
+ ![Segmented Decaying Log Distributed Velvet Noise](tests/plots/Segmented%20Decaying%20Log%20Distributed%20Velvet%20Noise%20Sequence.png)
25
+
26
+ ## Quick Start
27
+
28
+ First install the package into your environment:
29
+ ```pip install vndecorrelate```
30
+
31
+ Then load an audio file.
32
+
33
+ ```python
34
+ import scipy.io.wavfile as wavfile
35
+ from vndecorrelate.decorrelation import *
36
+
37
+ fs, input_signal = wavfile.read("audio/viola.wav")
38
+ ```
39
+
40
+ Then you can simply use the `VelvetNoise` class:
41
+
42
+ ```python
43
+ velvet_noise = VelvetNoise(
44
+ duration_seconds=0.03,
45
+ num_impulses=30,
46
+ )
47
+ output_signal = velvet_noise.decorrelate(input_signal)
48
+ ```
49
+ Or:
50
+
51
+ ```python
52
+ # manually generate the velvet noise as numpy NDArrays
53
+ velvet_noise = generate_velvet_noise(
54
+ duration_seconds=0.03,
55
+ num_impulses=30,
56
+ )
57
+ # numerically equivalent to VelvetNoise.convolve
58
+ output_signal = convolve_velvet_noise(input_signal, velvet_noise)
59
+ ```
60
+
61
+ Or you can create a chain of signal processors:
62
+
63
+ ```python
64
+ chain = (
65
+ SignalChain(sample_rate_hz=fs)
66
+ .velvet_noise(
67
+ duration_seconds=0.03,
68
+ num_impulses=30,
69
+ log_distribution_strength=1.0,
70
+ seed=1,
71
+ )
72
+ .haas_effect(
73
+ delay_time_seconds=0.02,
74
+ delayed_channel=1, # Right Channel
75
+ mode='LR',
76
+ )
77
+ )
78
+ # SignalChain is lazy, so instatiation of its signal processors happens here
79
+ output_signal = chain(input_signal)
80
+ ```
81
+ To listen back to the processed audio, simply save to a wav file locally.
82
+
83
+ ```python
84
+ wavfile.write('audio/viola_out.wav', fs, output_signal)
85
+ ```
86
+
87
+ ## Optimization
88
+ `optimization.py` contains functions for optimizing `VelvetNoise` or `HaasEffect` for maximizing stereo seperation while maintaining polar sample symmetry and mono compatiblilty.
89
+
90
+ `optimize_velvet_noise` optimizes the concentration of impulses towards the start of the filter: $\kappa \in [0.0, 1.0]$, referred to as `log_distribution_strength`.
91
+
92
+ `optimize_haas_delay` optimizes the `delay_time_seconds` parameter: $\tau \in [0.0, \text{max\\_delay\\_seconds}]$
93
+
94
+ `symmetry_aware_objective` takes the input signal and converts it to polar samples to compute the scalar objective function defined by:
95
+
96
+ $f(\alpha) = E_w[\theta^2] - \lambda_1(E_w[\theta])^2 - \lambda_2(E_w[\theta^3])^2 - \lambda_3r^2 - \lambda_4(max|{\theta}| - \phi)^2$
97
+
98
+ where $\alpha$ is the input scalar to optimize, each $E_w[\theta^n]$ is a moment of the polar sample distribution: $E_w[\theta^2]$ is the weighted angular variance, $(E_w[\theta])^2$ is the weighted mean (centroid), and $(E_w[\theta^3])^2$ is the skewness. $r$ is the correlation between the input left and right channels, $\phi$ is the `angle_limit` parameter, and each $\lambda_n$ is a penalty weight.
99
+
100
+ Sample runs of `VelvetNoise.decorrelate` with unoptimized and optimized filters can be compared by their polar sample plots generated from `plot_polar_sample`:
101
+
102
+ ![Unoptimized VN Vectorscope](tests/plots/Unoptimized%20VN%20Vectorscope.png)
103
+ ![VN Optimized Vectorscope](tests/plots/VN%20Optimized%20Vectorscope.png)
104
+
105
+ ## Visualization
106
+ 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.
107
+ ![Sine Sweep Signal](tests/plots/Sine%20Sweep%20Signal.png)
108
+ We can use the auto correlogram as a baseline:
109
+ ![Sine Sweep Auto Correlogram](tests/plots/Sine%20Sweep%20Auto%20Correlogram.png)
110
+ Plot the cross correlogram after filtering each channel with velvet noise:
111
+ ![Velvet Noise Filtered Sine Sweep Cross Correlogram](tests/plots/Velvet%20Noise%20Filtered%20Sine%20Sweep%20Cross%20Correlogram.png)
112
+ And compare to the behavior of filtering with white noise:
113
+ ![White Noise Filtered Sine Sweep Cross Correlogram](tests/plots/White%20Noise%20Filtered%20Sine%20Sweep%20Cross%20Correlogram.png)
114
+
115
+ ## References
116
+ <a id="1"> </a>
117
+ [1] “What is ‘Decorrelation’? | Sweetwater”. <a
118
+ href="https://www.sweetwater.com/insync/decorrelation/">
119
+ https://www.sweetwater.com/insync/decorrelation/</a> (accessed Aug. 10, 2020).
120
+
121
+ <a id="2"> </a>
122
+ [2] “Velvet-Noise Decorrelator”. <a
123
+ href="http://www.dafx17.eca.ed.ac.uk/papers/DAFx17_paper_96.pdf">
124
+ http://www.dafx17.eca.ed.ac.uk/papers/DAFx17_paper_96.pdf</a> (accessed Aug. 04, 2020).
@@ -0,0 +1,36 @@
1
+ [project]
2
+ name = "vndecorrelate"
3
+ version = "1.0.0"
4
+ description = "A Velvet-Noise Decorrelator for audio"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ authors = [
8
+ { name = "Christian Konstantinov", email = "ckonst98@gmail.com" }
9
+ ]
10
+
11
+ dependencies = [
12
+ "matplotlib>=3.10.3",
13
+ "numpy>=2.3.1",
14
+ "pillow==12.2.0",
15
+ "scipy>=1.16.0",
16
+ ]
17
+
18
+ [dependency-groups]
19
+ dev = [
20
+ "pytest>=9.0.3",
21
+ "ruff>=0.12.1",
22
+ "snakeviz>=2.2.2",
23
+ ]
24
+
25
+ [tool.ruff]
26
+ exclude = [".venv"]
27
+ fix = true
28
+
29
+ [tool.ruff.format]
30
+ quote-style = "single"
31
+
32
+ [tool.ruff.lint.flake8-quotes]
33
+ docstring-quotes = "single"
34
+
35
+ [tool.ruff.lint.pydocstyle]
36
+ convention = "numpy"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ __version__ = '0.0.0'