visqol-python 3.6.0__tar.gz → 3.7.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.
- {visqol_python-3.6.0 → visqol_python-3.7.0}/CHANGELOG.md +40 -0
- {visqol_python-3.6.0/visqol_python.egg-info → visqol_python-3.7.0}/PKG-INFO +5 -6
- {visqol_python-3.6.0 → visqol_python-3.7.0}/pyproject.toml +5 -6
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/__init__.py +1 -1
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/api.py +1 -2
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/patch_selector.py +16 -15
- {visqol_python-3.6.0 → visqol_python-3.7.0/visqol_python.egg-info}/PKG-INFO +5 -6
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol_python.egg-info/requires.txt +2 -8
- {visqol_python-3.6.0 → visqol_python-3.7.0}/CONTRIBUTING.md +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/LICENSE +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/MANIFEST.in +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/README.md +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/setup.cfg +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/tests/test_conformance.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/tests/test_parallel_correctness.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/tests/test_quick.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/__main__.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/alignment.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/analysis_window.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/audio_utils.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/gammatone.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/model/lattice_tcditugenmeetpackhref_ls2_nl60_lr12_bs2048_learn.005_ep2400_train1_7_raw.tflite +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/model/libsvm_nu_svr_model.txt +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/nsim.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/numba_accel.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/patch_creator.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/py.typed +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/quality_mapper.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/signal_utils.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/visqol_core.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol/visqol_manager.py +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol_python.egg-info/SOURCES.txt +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol_python.egg-info/dependency_links.txt +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol_python.egg-info/entry_points.txt +0 -0
- {visqol_python-3.6.0 → visqol_python-3.7.0}/visqol_python.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [3.7.0] - 2026-05-30
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Audio-mode C++ parity in fine realignment** (`finely_align_and_recreate_patches`):
|
|
11
|
+
the previous "B2 optimisation" skipped the per-patch spectrogram rebuild
|
|
12
|
+
whenever the fine-alignment lag was zero, on the assumption that the rebuilt
|
|
13
|
+
spectrogram would be identical to the original patch. That assumption is
|
|
14
|
+
wrong. The original patch is sliced out of the **full-signal** Gammatone
|
|
15
|
+
spectrogram (warm IIR filter state, carrying history), whereas the rebuild
|
|
16
|
+
runs Gammatone over the **sliced** audio from a cold filter state — so the
|
|
17
|
+
leading frames differ even when no shift is applied. C++ ViSQOL always
|
|
18
|
+
rebuilds and keeps whichever scores higher, so skipping it silently dropped
|
|
19
|
+
that improvement. The skip is removed; every matched patch is now rebuilt and
|
|
20
|
+
compared, exactly as C++ does.
|
|
21
|
+
- **Impact:** audio MOS-LQO now matches the C++ binary to ULP. Max diff over
|
|
22
|
+
the 10 conformance cases dropped from **2.41 × 10⁻² → 1.17 × 10⁻⁴**; 9 of 10
|
|
23
|
+
cases are bit-exact (~10⁻¹⁴). The lone residual (`contrabassoon_24aac`,
|
|
24
|
+
1.17 × 10⁻⁴) is an unrelated sub-sample boundary-patch alignment rounding,
|
|
25
|
+
now smaller than the speech-mode parity gap.
|
|
26
|
+
- Existing audio scores shift by up to ~0.024 MOS where they were previously
|
|
27
|
+
too low; this is a move **toward** the C++ ground truth, not away from it.
|
|
28
|
+
- Speech polynomial and lattice scores are unaffected (bit-identical before
|
|
29
|
+
and after).
|
|
30
|
+
|
|
31
|
+
### Performance
|
|
32
|
+
- Fine realignment now rebuilds the spectrogram for every patch (including
|
|
33
|
+
`lag == 0`), so it no longer benefits from the zero-lag skip. Net effect is
|
|
34
|
+
roughly **1.4–1.5× slower realignment** (e.g. `guitar48_stereo` 0.44 s → 0.65 s
|
|
35
|
+
end-to-end with Numba + pyFFTW). This is the cost of exact C++ parity and is
|
|
36
|
+
consistent with the project's precision-first policy. Audio-mode RTF rises
|
|
37
|
+
from ~0.036 (3.6.0) to ~0.054 — still ~1.7× faster than the C++ binary
|
|
38
|
+
(~0.093) and faster than 3.5.0 (~0.067).
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- **Dropped Python 3.9 support** (`requires-python = ">=3.10"`). Downstream
|
|
42
|
+
projects still on 3.9 should pin `visqol-python<3.7`.
|
|
43
|
+
- CI: bumped GitHub Actions to Node-24-compatible major versions
|
|
44
|
+
(checkout v5, setup-python v6, upload/download-artifact v5).
|
|
45
|
+
|
|
7
46
|
## [3.6.0] - 2026-05-27
|
|
8
47
|
|
|
9
48
|
### Added
|
|
@@ -218,6 +257,7 @@ All v3.5.0 conformance baselines preserved within ULP precision:
|
|
|
218
257
|
- Bundled SVR model (`libsvm_nu_svr_model.txt`)
|
|
219
258
|
- GitHub Actions workflow for auto-publish to PyPI via Trusted Publisher
|
|
220
259
|
|
|
260
|
+
[3.7.0]: https://github.com/talker93/visqol-python/compare/v3.6.0...v3.7.0
|
|
221
261
|
[3.6.0]: https://github.com/talker93/visqol-python/compare/v3.5.0...v3.6.0
|
|
222
262
|
[3.5.0]: https://github.com/talker93/visqol-python/compare/v3.4.0...v3.5.0
|
|
223
263
|
[3.4.0]: https://github.com/talker93/visqol-python/compare/v3.3.6...v3.4.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: visqol-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: ViSQOL - Virtual Speech Quality Objective Listener (Pure Python)
|
|
5
5
|
Author: Shan Jiang
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -14,7 +14,6 @@ Classifier: Development Status :: 4 - Beta
|
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Intended Audience :: Science/Research
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -22,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
21
|
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
23
22
|
Classifier: Topic :: Scientific/Engineering
|
|
24
23
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.10
|
|
26
25
|
Description-Content-Type: text/markdown
|
|
27
26
|
License-File: LICENSE
|
|
28
27
|
Requires-Dist: numpy>=1.20
|
|
@@ -32,12 +31,12 @@ Requires-Dist: libsvm-official>=3.25
|
|
|
32
31
|
Provides-Extra: accel
|
|
33
32
|
Requires-Dist: numba>=0.57; extra == "accel"
|
|
34
33
|
Provides-Extra: lattice
|
|
35
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
34
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "lattice"
|
|
36
35
|
Provides-Extra: fftw
|
|
37
36
|
Requires-Dist: pyfftw>=0.13; extra == "fftw"
|
|
38
37
|
Provides-Extra: all
|
|
39
38
|
Requires-Dist: numba>=0.57; extra == "all"
|
|
40
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
39
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "all"
|
|
41
40
|
Requires-Dist: pyfftw>=0.13; extra == "all"
|
|
42
41
|
Provides-Extra: test
|
|
43
42
|
Requires-Dist: pytest>=7.0; extra == "test"
|
|
@@ -46,7 +45,7 @@ Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
46
45
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
47
46
|
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
48
47
|
Requires-Dist: numba>=0.57; extra == "dev"
|
|
49
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
48
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "dev"
|
|
50
49
|
Requires-Dist: pyfftw>=0.13; extra == "dev"
|
|
51
50
|
Dynamic: license-file
|
|
52
51
|
|
|
@@ -8,7 +8,7 @@ dynamic = ["version"]
|
|
|
8
8
|
description = "ViSQOL - Virtual Speech Quality Objective Listener (Pure Python)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
12
|
authors = [
|
|
13
13
|
{name = "Shan Jiang"},
|
|
14
14
|
]
|
|
@@ -22,7 +22,6 @@ classifiers = [
|
|
|
22
22
|
"Intended Audience :: Developers",
|
|
23
23
|
"Intended Audience :: Science/Research",
|
|
24
24
|
"Programming Language :: Python :: 3",
|
|
25
|
-
"Programming Language :: Python :: 3.9",
|
|
26
25
|
"Programming Language :: Python :: 3.10",
|
|
27
26
|
"Programming Language :: Python :: 3.11",
|
|
28
27
|
"Programming Language :: Python :: 3.12",
|
|
@@ -40,11 +39,11 @@ dependencies = [
|
|
|
40
39
|
|
|
41
40
|
[project.optional-dependencies]
|
|
42
41
|
accel = ["numba>=0.57"]
|
|
43
|
-
lattice = ["ai-edge-litert>=2.1.5
|
|
42
|
+
lattice = ["ai-edge-litert>=2.1.5"]
|
|
44
43
|
fftw = ["pyfftw>=0.13"]
|
|
45
44
|
all = [
|
|
46
45
|
"numba>=0.57",
|
|
47
|
-
"ai-edge-litert>=2.1.5
|
|
46
|
+
"ai-edge-litert>=2.1.5",
|
|
48
47
|
"pyfftw>=0.13",
|
|
49
48
|
]
|
|
50
49
|
test = ["pytest>=7.0"]
|
|
@@ -53,7 +52,7 @@ dev = [
|
|
|
53
52
|
"ruff>=0.4",
|
|
54
53
|
"mypy>=1.8",
|
|
55
54
|
"numba>=0.57",
|
|
56
|
-
"ai-edge-litert>=2.1.5
|
|
55
|
+
"ai-edge-litert>=2.1.5",
|
|
57
56
|
"pyfftw>=0.13",
|
|
58
57
|
]
|
|
59
58
|
|
|
@@ -80,7 +79,7 @@ visqol = ["model/*.txt", "model/*.tflite", "py.typed"]
|
|
|
80
79
|
testpaths = ["tests"]
|
|
81
80
|
|
|
82
81
|
[tool.ruff]
|
|
83
|
-
target-version = "
|
|
82
|
+
target-version = "py310"
|
|
84
83
|
line-length = 95
|
|
85
84
|
|
|
86
85
|
[tool.ruff.lint]
|
|
@@ -10,9 +10,8 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
-
from collections.abc import Sequence
|
|
13
|
+
from collections.abc import Callable, Sequence
|
|
14
14
|
from concurrent.futures import ProcessPoolExecutor, as_completed
|
|
15
|
-
from typing import Callable
|
|
16
15
|
|
|
17
16
|
import numpy as np
|
|
18
17
|
from numpy.typing import NDArray
|
|
@@ -469,14 +469,19 @@ def finely_align_and_recreate_patches(
|
|
|
469
469
|
|
|
470
470
|
1. Extract audio sub-signals
|
|
471
471
|
2. Re-align at fine granularity
|
|
472
|
-
3.
|
|
473
|
-
4.
|
|
474
|
-
5.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
472
|
+
3. Rebuild spectrograms from the (re)aligned audio slices
|
|
473
|
+
4. Recompute NSIM
|
|
474
|
+
5. Keep the better result (original or re-aligned)
|
|
475
|
+
|
|
476
|
+
The rebuild is performed for **every** patch, including those with
|
|
477
|
+
``lag == 0``. This mirrors C++ exactly: the original patch was sliced
|
|
478
|
+
out of the *full-signal* spectrogram (its Gammatone IIR state is warm,
|
|
479
|
+
carrying history from earlier samples), whereas the rebuilt patch runs
|
|
480
|
+
Gammatone over the *sliced* audio from a cold filter state. The two
|
|
481
|
+
therefore differ in their leading frames even when no time shift is
|
|
482
|
+
applied, and C++ keeps whichever scores higher. Skipping the rebuild
|
|
483
|
+
on ``lag == 0`` (a former "optimisation") silently dropped this
|
|
484
|
+
improvement and broke audio-mode C++ parity by up to ~0.024 MOS.
|
|
480
485
|
"""
|
|
481
486
|
realigned_results: list[PatchSimilarityResult] = list(sim_results)
|
|
482
487
|
|
|
@@ -506,17 +511,13 @@ def finely_align_and_recreate_patches(
|
|
|
506
511
|
except Exception:
|
|
507
512
|
continue
|
|
508
513
|
|
|
509
|
-
# B2 optimisation: if lag is zero, alignment didn't change anything.
|
|
510
|
-
# The rebuilt spectrogram would be identical to the original, so the
|
|
511
|
-
# recomputed NSIM would also be identical — skip the expensive rebuild.
|
|
512
|
-
if lag == 0.0:
|
|
513
|
-
continue
|
|
514
|
-
|
|
515
514
|
# Check we have enough samples
|
|
516
515
|
if len(ref_aligned.data) <= window.size or len(deg_aligned.data) <= window.size:
|
|
517
516
|
continue
|
|
518
517
|
|
|
519
|
-
# 3. Rebuild spectrograms (
|
|
518
|
+
# 3. Rebuild spectrograms from the aligned slices (always — see docstring:
|
|
519
|
+
# cold vs warm Gammatone state makes this differ from the original
|
|
520
|
+
# patch even when lag == 0, so it is not a redundant recompute).
|
|
520
521
|
try:
|
|
521
522
|
ref_spec = spect_builder.build(ref_aligned, window)
|
|
522
523
|
deg_spec = spect_builder.build(deg_aligned, window)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: visqol-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: ViSQOL - Virtual Speech Quality Objective Listener (Pure Python)
|
|
5
5
|
Author: Shan Jiang
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -14,7 +14,6 @@ Classifier: Development Status :: 4 - Beta
|
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Intended Audience :: Science/Research
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -22,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
21
|
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
23
22
|
Classifier: Topic :: Scientific/Engineering
|
|
24
23
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python: >=3.
|
|
24
|
+
Requires-Python: >=3.10
|
|
26
25
|
Description-Content-Type: text/markdown
|
|
27
26
|
License-File: LICENSE
|
|
28
27
|
Requires-Dist: numpy>=1.20
|
|
@@ -32,12 +31,12 @@ Requires-Dist: libsvm-official>=3.25
|
|
|
32
31
|
Provides-Extra: accel
|
|
33
32
|
Requires-Dist: numba>=0.57; extra == "accel"
|
|
34
33
|
Provides-Extra: lattice
|
|
35
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
34
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "lattice"
|
|
36
35
|
Provides-Extra: fftw
|
|
37
36
|
Requires-Dist: pyfftw>=0.13; extra == "fftw"
|
|
38
37
|
Provides-Extra: all
|
|
39
38
|
Requires-Dist: numba>=0.57; extra == "all"
|
|
40
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
39
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "all"
|
|
41
40
|
Requires-Dist: pyfftw>=0.13; extra == "all"
|
|
42
41
|
Provides-Extra: test
|
|
43
42
|
Requires-Dist: pytest>=7.0; extra == "test"
|
|
@@ -46,7 +45,7 @@ Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
46
45
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
47
46
|
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
48
47
|
Requires-Dist: numba>=0.57; extra == "dev"
|
|
49
|
-
Requires-Dist: ai-edge-litert>=2.1.5;
|
|
48
|
+
Requires-Dist: ai-edge-litert>=2.1.5; extra == "dev"
|
|
50
49
|
Requires-Dist: pyfftw>=0.13; extra == "dev"
|
|
51
50
|
Dynamic: license-file
|
|
52
51
|
|
|
@@ -8,27 +8,21 @@ numba>=0.57
|
|
|
8
8
|
|
|
9
9
|
[all]
|
|
10
10
|
numba>=0.57
|
|
11
|
-
pyfftw>=0.13
|
|
12
|
-
|
|
13
|
-
[all:python_version >= "3.10"]
|
|
14
11
|
ai-edge-litert>=2.1.5
|
|
12
|
+
pyfftw>=0.13
|
|
15
13
|
|
|
16
14
|
[dev]
|
|
17
15
|
pytest>=7.0
|
|
18
16
|
ruff>=0.4
|
|
19
17
|
mypy>=1.8
|
|
20
18
|
numba>=0.57
|
|
21
|
-
pyfftw>=0.13
|
|
22
|
-
|
|
23
|
-
[dev:python_version >= "3.10"]
|
|
24
19
|
ai-edge-litert>=2.1.5
|
|
20
|
+
pyfftw>=0.13
|
|
25
21
|
|
|
26
22
|
[fftw]
|
|
27
23
|
pyfftw>=0.13
|
|
28
24
|
|
|
29
25
|
[lattice]
|
|
30
|
-
|
|
31
|
-
[lattice:python_version >= "3.10"]
|
|
32
26
|
ai-edge-litert>=2.1.5
|
|
33
27
|
|
|
34
28
|
[test]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|