vl8 0.2.0__tar.gz → 0.3.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.
- vl8-0.3.0/PKG-INFO +51 -0
- vl8-0.3.0/README.md +21 -0
- vl8-0.3.0/pyproject.toml +58 -0
- vl8-0.3.0/vl8/.DS_Store +0 -0
- vl8-0.3.0/vl8/__init__.py +0 -0
- vl8-0.3.0/vl8/adaptor/__init__.py +0 -0
- vl8-0.3.0/vl8/dsp/__init__.py +0 -0
- vl8-0.3.0/vl8/dsp/fix_gaps.py +49 -0
- vl8-0.3.0/vl8/processor/__init__.py +0 -0
- vl8-0.3.0/vl8/processor/catenate.py +62 -0
- vl8-0.2.0/PKG-INFO +0 -22
- vl8-0.2.0/README.rst +0 -4
- vl8-0.2.0/pyproject.toml +0 -7
- vl8-0.2.0/setup.cfg +0 -7
- vl8-0.2.0/setup.py +0 -38
- vl8-0.2.0/vl8.egg-info/PKG-INFO +0 -22
- vl8-0.2.0/vl8.egg-info/SOURCES.txt +0 -10
- vl8-0.2.0/vl8.egg-info/dependency_links.txt +0 -1
- vl8-0.2.0/vl8.egg-info/requires.txt +0 -5
- vl8-0.2.0/vl8.egg-info/top_level.txt +0 -1
- vl8-0.2.0/vl8.py +0 -81
vl8-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vl8
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: 🔉 Perturbed audio 🔉
|
|
5
|
+
Author: Tom Ritchford
|
|
6
|
+
Author-email: Tom Ritchford <tom@swirly.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: abbrev>=1.0.1,<2
|
|
15
|
+
Requires-Dist: graycode>=1.0.5,<2
|
|
16
|
+
Requires-Dist: more-itertools>=9.0.0,<10
|
|
17
|
+
Requires-Dist: numpy>=1.24.1,<2
|
|
18
|
+
Requires-Dist: pydub>=0.25.1,<0.26
|
|
19
|
+
Requires-Dist: pyyaml>=6.0,<7
|
|
20
|
+
Requires-Dist: runs>=1.1.0,<2
|
|
21
|
+
Requires-Dist: soundfile>=0.11.0,<0.12
|
|
22
|
+
Requires-Dist: stroll>=1.1.0,<2
|
|
23
|
+
Requires-Dist: tdir>=1.4.1,<2
|
|
24
|
+
Requires-Dist: toml>=0.10.2,<0.11
|
|
25
|
+
Requires-Dist: typeguard>=2.13.3,<3
|
|
26
|
+
Requires-Dist: wavemap>=2.0.1,<3
|
|
27
|
+
Requires-Dist: xmod>=1.3.2,<2
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# 🔉 vl8: Create derivative works that might not be copyright violations 🔉
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
Update: this is still in development - I got sidetracked by paying work.
|
|
36
|
+
Most of this is working, it just needs to be packaged!
|
|
37
|
+
|
|
38
|
+
------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
A command line tool and Python library that (will soon be) like a Swiss
|
|
41
|
+
Army Knife for audio.
|
|
42
|
+
|
|
43
|
+
- Create a myriad of mashups of your favorite audio effortlessly.
|
|
44
|
+
- Script mundane tasks like editing, scaling and stretching,
|
|
45
|
+
envelopes, playlists and more.
|
|
46
|
+
- Handle very large audio files using memory mapping, or very large
|
|
47
|
+
numbers of audio files using scripting.
|
|
48
|
+
- Write your own scripts for mashups or editing, or your own plug-ins,
|
|
49
|
+
and share them.
|
|
50
|
+
- Uses widely compatible, highly performant numpy arrays to represent
|
|
51
|
+
audio files within Python.
|
vl8-0.3.0/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 🔉 vl8: Create derivative works that might not be copyright violations 🔉
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Update: this is still in development - I got sidetracked by paying work.
|
|
6
|
+
Most of this is working, it just needs to be packaged!
|
|
7
|
+
|
|
8
|
+
------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
A command line tool and Python library that (will soon be) like a Swiss
|
|
11
|
+
Army Knife for audio.
|
|
12
|
+
|
|
13
|
+
- Create a myriad of mashups of your favorite audio effortlessly.
|
|
14
|
+
- Script mundane tasks like editing, scaling and stretching,
|
|
15
|
+
envelopes, playlists and more.
|
|
16
|
+
- Handle very large audio files using memory mapping, or very large
|
|
17
|
+
numbers of audio files using scripting.
|
|
18
|
+
- Write your own scripts for mashups or editing, or your own plug-ins,
|
|
19
|
+
and share them.
|
|
20
|
+
- Uses widely compatible, highly performant numpy arrays to represent
|
|
21
|
+
audio files within Python.
|
vl8-0.3.0/pyproject.toml
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "vl8"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "🔉 Perturbed audio 🔉"
|
|
5
|
+
authors = [{ name = "Tom Ritchford", email = "tom@swirly.com" }]
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
classifiers = ["Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14"]
|
|
10
|
+
dependencies = [
|
|
11
|
+
"abbrev>=1.0.1,<2",
|
|
12
|
+
"graycode>=1.0.5,<2",
|
|
13
|
+
"more-itertools>=9.0.0,<10",
|
|
14
|
+
"numpy>=1.24.1,<2",
|
|
15
|
+
"pydub>=0.25.1,<0.26",
|
|
16
|
+
"pyyaml>=6.0,<7",
|
|
17
|
+
"runs>=1.1.0,<2",
|
|
18
|
+
"soundfile>=0.11.0,<0.12",
|
|
19
|
+
"stroll>=1.1.0,<2",
|
|
20
|
+
"tdir>=1.4.1,<2",
|
|
21
|
+
"toml>=0.10.2,<0.11",
|
|
22
|
+
"typeguard>=2.13.3,<3",
|
|
23
|
+
"wavemap>=2.0.1,<3",
|
|
24
|
+
"xmod>=1.3.2,<2",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[tool.doks]
|
|
28
|
+
auto = true
|
|
29
|
+
|
|
30
|
+
[tool.ruff]
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = [
|
|
33
|
+
"coverage>=7.1.0,<8",
|
|
34
|
+
"impall>=1.1.1,<2",
|
|
35
|
+
"pytest>=7.2.1,<8",
|
|
36
|
+
"pyupgrade>=3.21.2",
|
|
37
|
+
"ruff>=0.14.14",
|
|
38
|
+
"tdir>=1.4.1,<2",
|
|
39
|
+
"ty>=0.0.14",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[tool.uv]
|
|
43
|
+
|
|
44
|
+
[tool.uv.build-backend]
|
|
45
|
+
module-root = ""
|
|
46
|
+
|
|
47
|
+
[build-system]
|
|
48
|
+
requires = ["uv_build>=0.9.0,<0.10.0"]
|
|
49
|
+
build-backend = "uv_build"
|
|
50
|
+
[tool.coverage.run]
|
|
51
|
+
branch = true
|
|
52
|
+
source = "vl8"
|
|
53
|
+
|
|
54
|
+
[tool.coverage.report]
|
|
55
|
+
fail_under = "60"
|
|
56
|
+
skip_covered = true
|
|
57
|
+
exclude_lines = ["pragma: no cover", "if False:", "if __name__ == .__main__.:", "raise NotImplementedError"]
|
|
58
|
+
|
vl8-0.3.0/vl8/.DS_Store
ADDED
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from typing import List, Optional, Union
|
|
3
|
+
|
|
4
|
+
import xmod
|
|
5
|
+
|
|
6
|
+
from old.vl8.util import error
|
|
7
|
+
|
|
8
|
+
Number = Union[int, float]
|
|
9
|
+
Gaps = Union[Number, List[Number]]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@xmod
|
|
13
|
+
def fix_gaps(
|
|
14
|
+
durations: List[int],
|
|
15
|
+
gaps: Gaps,
|
|
16
|
+
pre: float = 0,
|
|
17
|
+
post: float = 0,
|
|
18
|
+
sample_rate: Optional[int] = None,
|
|
19
|
+
):
|
|
20
|
+
# TODO: fix_gaps should learn about durations amd ration
|
|
21
|
+
if pre < 0 or post < 0:
|
|
22
|
+
raise ValueError("pre and post cannot be negative")
|
|
23
|
+
|
|
24
|
+
if not isinstance(gaps, list):
|
|
25
|
+
gaps = [gaps]
|
|
26
|
+
elif not gaps:
|
|
27
|
+
raise ValueError("gap must be a non-empty list or an integer")
|
|
28
|
+
|
|
29
|
+
n = len(durations)
|
|
30
|
+
scale = math.ceil(n / len(gaps))
|
|
31
|
+
gaps = [pre] + (gaps * scale)[: n - 1] + [post]
|
|
32
|
+
|
|
33
|
+
if sample_rate:
|
|
34
|
+
gaps = [g * sample_rate for g in gaps]
|
|
35
|
+
|
|
36
|
+
gaps = [round(g) for g in gaps]
|
|
37
|
+
|
|
38
|
+
# Fix any fade gaps that are too long.
|
|
39
|
+
for i, gap in enumerate(gaps):
|
|
40
|
+
if i > 0:
|
|
41
|
+
gap = max(gap, -durations[i - 1])
|
|
42
|
+
if i < n:
|
|
43
|
+
gap = max(gap, -durations[i])
|
|
44
|
+
if gaps[i] != gap:
|
|
45
|
+
error(f"Gap {i}: {gap} was longer than the sample!")
|
|
46
|
+
gaps[i] = gap
|
|
47
|
+
|
|
48
|
+
assert len(gaps) == n + 1
|
|
49
|
+
return gaps
|
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from old.vl8.dsp import curve_cache
|
|
4
|
+
from old.vl8.function.creator import Creator
|
|
5
|
+
from vl8.dsp import fix_gaps
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class Catenate(Creator):
|
|
10
|
+
curve: curve_cache.Curve = None
|
|
11
|
+
gap: fix_gaps.Gaps = 0
|
|
12
|
+
pre: int = 0
|
|
13
|
+
post: int = 0
|
|
14
|
+
|
|
15
|
+
def _prepare(self, src):
|
|
16
|
+
durations = [s.shape[1] for s in src]
|
|
17
|
+
self.gaps = fix_gaps(
|
|
18
|
+
durations, self.gap, self.pre, self.post, src[0].sample_rate
|
|
19
|
+
)
|
|
20
|
+
return sum(durations) + sum(self.gaps)
|
|
21
|
+
|
|
22
|
+
def _call(self, arr, *src):
|
|
23
|
+
"""
|
|
24
|
+
gap: None, a number of seconds or a list of seconds
|
|
25
|
+
if a gap is negative, it's a fade
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
fader = curve_cache(self.curve, arr.dtype)
|
|
29
|
+
|
|
30
|
+
begin = end = 0
|
|
31
|
+
for i, s in enumerate(src):
|
|
32
|
+
begin = end + self.gaps[i]
|
|
33
|
+
end = begin + s.shape[-1]
|
|
34
|
+
fade_in, fade_out = -self.gaps[i], -self.gaps[i + 1]
|
|
35
|
+
|
|
36
|
+
b, e = begin, end
|
|
37
|
+
if fade_in > 0:
|
|
38
|
+
delta = fader(0, 1, fade_in) * s[:, :fade_in]
|
|
39
|
+
arr[:, b : b + fade_in] += delta
|
|
40
|
+
b += fade_in
|
|
41
|
+
|
|
42
|
+
if fade_out > 0:
|
|
43
|
+
delta = fader(1, 0, fade_out) * s[:, -fade_out:]
|
|
44
|
+
arr[:, e - fade_out : e] += delta
|
|
45
|
+
e -= fade_out
|
|
46
|
+
|
|
47
|
+
arr[:, b:e] += s[:, b - begin : e - end or None]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
# Should be elsewhere in a task
|
|
52
|
+
|
|
53
|
+
overlap: None or any floating point numbers, referenced to the longest item.
|
|
54
|
+
|
|
55
|
+
These next comments shoul
|
|
56
|
+
|
|
57
|
+
0 means: all start together
|
|
58
|
+
0.5 means: middles of all songs are at same time
|
|
59
|
+
1 means: all end together
|
|
60
|
+
|
|
61
|
+
Negative numbers and numbers bigger than one are possible!
|
|
62
|
+
"""
|
vl8-0.2.0/PKG-INFO
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: vl8
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: 🔉 vl8: Sort audio granularly 🔉
|
|
5
|
-
Home-page: https://github.com/rec/vl8
|
|
6
|
-
Author: Tom Ritchford
|
|
7
|
-
Author-email: tom@swirly.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Description: 🔉 vl8: Create derivative works that might not be copyright violations 🔉
|
|
10
|
-
----------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
This is a tool to create derivative works of pieces of music.
|
|
13
|
-
|
|
14
|
-
Keywords: audio
|
|
15
|
-
Platform: UNKNOWN
|
|
16
|
-
Classifier: Development Status :: 3 - Alpha
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
-
Classifier: Intended Audience :: Developers
|
|
22
|
-
Classifier: License :: OSI Approved :: MIT License
|
vl8-0.2.0/README.rst
DELETED
vl8-0.2.0/pyproject.toml
DELETED
vl8-0.2.0/setup.cfg
DELETED
vl8-0.2.0/setup.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
_classifiers = [
|
|
5
|
-
'Development Status :: 3 - Alpha',
|
|
6
|
-
'Programming Language :: Python :: 3.6',
|
|
7
|
-
'Programming Language :: Python :: 3.7',
|
|
8
|
-
'Programming Language :: Python :: 3.8',
|
|
9
|
-
'Programming Language :: Python :: 3.9',
|
|
10
|
-
'Intended Audience :: Developers',
|
|
11
|
-
'License :: OSI Approved :: MIT License',
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def _version():
|
|
16
|
-
with open('vl8.py') as fp:
|
|
17
|
-
line = next(i for i in fp if i.startswith('__version__'))
|
|
18
|
-
return line.strip().split()[-1].strip("'")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
REQUIREMENTS = Path('requirements.txt').read_text().splitlines()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if __name__ == '__main__':
|
|
25
|
-
setup(
|
|
26
|
-
name='vl8',
|
|
27
|
-
version=_version(),
|
|
28
|
-
author='Tom Ritchford',
|
|
29
|
-
author_email='tom@swirly.com',
|
|
30
|
-
url='https://github.com/rec/vl8',
|
|
31
|
-
py_modules=['vl8'],
|
|
32
|
-
description='🔉 vl8: Sort audio granularly 🔉',
|
|
33
|
-
long_description=open('README.rst').read(),
|
|
34
|
-
license='MIT',
|
|
35
|
-
classifiers=_classifiers,
|
|
36
|
-
keywords=['audio'],
|
|
37
|
-
install_requires=REQUIREMENTS,
|
|
38
|
-
)
|
vl8-0.2.0/vl8.egg-info/PKG-INFO
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: vl8
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: 🔉 vl8: Sort audio granularly 🔉
|
|
5
|
-
Home-page: https://github.com/rec/vl8
|
|
6
|
-
Author: Tom Ritchford
|
|
7
|
-
Author-email: tom@swirly.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Description: 🔉 vl8: Create derivative works that might not be copyright violations 🔉
|
|
10
|
-
----------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
This is a tool to create derivative works of pieces of music.
|
|
13
|
-
|
|
14
|
-
Keywords: audio
|
|
15
|
-
Platform: UNKNOWN
|
|
16
|
-
Classifier: Development Status :: 3 - Alpha
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
-
Classifier: Intended Audience :: Developers
|
|
22
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
vl8
|
vl8-0.2.0/vl8.py
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
🏃 Run one or more commands 🏃
|
|
3
|
-
------------------------------------------------------------------
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# import stroll
|
|
8
|
-
from dataclasses import dataclass
|
|
9
|
-
import numpy as np
|
|
10
|
-
import util
|
|
11
|
-
|
|
12
|
-
__all__ = 'vl8'
|
|
13
|
-
__version__ = '0.2.0'
|
|
14
|
-
INFILE = '/data/vl8/full.wav'
|
|
15
|
-
MAX_FRAME = 4096
|
|
16
|
-
SAMPLERATE = 44100
|
|
17
|
-
GRAIN_SIZE = SAMPLERATE // 10
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def mean_square(granule):
|
|
21
|
-
return np.mean(granule * granule)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@dataclass
|
|
25
|
-
class Granulator:
|
|
26
|
-
filename: str
|
|
27
|
-
grain_size: int = GRAIN_SIZE
|
|
28
|
-
sort: bool = True
|
|
29
|
-
duration: int = 0
|
|
30
|
-
|
|
31
|
-
def __post_init__(self):
|
|
32
|
-
assert not (self.grain_size % 2)
|
|
33
|
-
self.buffer = util.read(self.filename, self.grain_size, self.duration)
|
|
34
|
-
self.duration = self.buffer.shape[1]
|
|
35
|
-
|
|
36
|
-
def run(self, function, outfile):
|
|
37
|
-
results = self.for_each_granule(function)
|
|
38
|
-
results.sort(1)
|
|
39
|
-
print('writing', outfile)
|
|
40
|
-
util.write(outfile, self.combine(results))
|
|
41
|
-
|
|
42
|
-
def for_each_granule(self, function):
|
|
43
|
-
half = self.grain_size // 2
|
|
44
|
-
granules = self.duration // half
|
|
45
|
-
granules = round(granules)
|
|
46
|
-
|
|
47
|
-
results = util.empty(granules).transpose()
|
|
48
|
-
for i in range(granules):
|
|
49
|
-
begin = half * i
|
|
50
|
-
end = begin + self.grain_size
|
|
51
|
-
value = function(self.buffer[:, begin:end])
|
|
52
|
-
results[i] = float(i), value
|
|
53
|
-
|
|
54
|
-
return results
|
|
55
|
-
|
|
56
|
-
def combine(self, results):
|
|
57
|
-
half = self.grain_size // 2
|
|
58
|
-
buf = self.buffer
|
|
59
|
-
out = util.zeros(buf.shape[1] + half)
|
|
60
|
-
|
|
61
|
-
fade_in = np.linspace(0, 1, half, dtype=util.FLOAT)
|
|
62
|
-
fade_out = np.flip(fade_in)
|
|
63
|
-
|
|
64
|
-
for out_index, (in_index, value) in enumerate(results):
|
|
65
|
-
i = round(in_index) * half
|
|
66
|
-
o = out_index * half
|
|
67
|
-
out[:, o : o + half] += buf[:, i : i + half] * fade_in
|
|
68
|
-
|
|
69
|
-
i += half
|
|
70
|
-
o += half
|
|
71
|
-
out[:, o : o + half] += buf[:, i : i + half] * fade_out
|
|
72
|
-
|
|
73
|
-
return out
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if __name__ == '__main__':
|
|
77
|
-
print('Reading', INFILE)
|
|
78
|
-
generator = Granulator(INFILE)
|
|
79
|
-
|
|
80
|
-
print('Running mean_square')
|
|
81
|
-
generator.run(mean_square, '/data/vl8/mean_square.wav')
|