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 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
+ ![vl8 logo](https://raw.githubusercontent.com/rec/vl8/master/vl8.png)
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
+ ![vl8 logo](https://raw.githubusercontent.com/rec/vl8/master/vl8.png)
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.
@@ -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
+
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
@@ -1,4 +0,0 @@
1
- 🔉 vl8: Create derivative works that might not be copyright violations 🔉
2
- ----------------------------------------------------------------------------
3
-
4
- This is a tool to create derivative works of pieces of music.
vl8-0.2.0/pyproject.toml DELETED
@@ -1,7 +0,0 @@
1
- [tool.black]
2
- line-length = 79
3
- skip-string-normalization = true
4
- target-version = ['py37']
5
-
6
- [tool.doks]
7
- auto = true
vl8-0.2.0/setup.cfg DELETED
@@ -1,7 +0,0 @@
1
- [metadata]
2
- description-file = README.rst
3
-
4
- [egg_info]
5
- tag_build =
6
- tag_date = 0
7
-
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
- )
@@ -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,10 +0,0 @@
1
- README.rst
2
- pyproject.toml
3
- setup.cfg
4
- setup.py
5
- vl8.py
6
- vl8.egg-info/PKG-INFO
7
- vl8.egg-info/SOURCES.txt
8
- vl8.egg-info/dependency_links.txt
9
- vl8.egg-info/requires.txt
10
- vl8.egg-info/top_level.txt
@@ -1 +0,0 @@
1
-
@@ -1,5 +0,0 @@
1
- aubio
2
- numpy
3
- pydub
4
- runs
5
- stroll
@@ -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')