Skip to content

feat(core): add volume_multiplier to control output loudness (#362) - #393

Open
ousamabenyounes wants to merge 1 commit into
OpenBMB:mainfrom
ousamabenyounes:fix/issue-362
Open

feat(core): add volume_multiplier to control output loudness (#362)#393
ousamabenyounes wants to merge 1 commit into
OpenBMB:mainfrom
ousamabenyounes:fix/issue-362

Conversation

@ousamabenyounes

Copy link
Copy Markdown

Add a positive volume_multiplier param to VoxCPM.generate/_generate that linearly scales the output waveform relative to the model's natural (reference-matched) level, with peak-limiting to avoid clipping. Gives the numeric, reproducible volume knob issue #362 asks for instead of relying only on prompt wording.

Test verification (RED → GREEN)

With the fix reverted, the new test fails (RED):

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <voxcpm.core.VoxCPM object at 0x723673639be0>, args = ()
kwargs = {'text': 'hello world', 'volume_multiplier': 2.0}

    def generate(self, *args, **kwargs) -> np.ndarray:
>       return next_and_close(self._generate(*args, streaming=False, **kwargs))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: VoxCPM._generate() got an unexpected keyword argument 'volume_multiplier'

src/voxcpm/core.py:178: TypeError
_________________ test_generate_rejects_nonpositive_multiplier _________________

monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7236736968b0>

    def test_generate_rejects_nonpositive_multiplier(monkeypatch):
        inst, _ = _make_pipeline(monkeypatch)
        with pytest.raises(ValueError, match="volume_multiplier must be positive"):
>           inst.generate(text="hello world", volume_multiplier=0.0)

tests/test_volume.py:128: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <voxcpm.core.VoxCPM object at 0x7236736cd810>, args = ()
kwargs = {'text': 'hello world', 'volume_multiplier': 0.0}

    def generate(self, *args, **kwargs) -> np.ndarray:
>       return next_and_close(self._generate(*args, streaming=False, **kwargs))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       TypeError: VoxCPM._generate() got an unexpected keyword argument 'volume_multiplier'

src/voxcpm/core.py:178: TypeError
=========================== short test summary info ============================
FAILED tests/test_volume.py::test_identity_multiplier_is_noop - AttributeErro...
FAILED tests/test_volume.py::test_multiplier_scales_rms_linearly - AttributeE...
FAILED tests/test_volume.py::test_peak_limited_to_avoid_clipping - AttributeE...
FAILED tests/test_volume.py::test_empty_waveform_untouched - AttributeError: ...
FAILED tests/test_volume.py::test_generate_applies_multiplier_end_to_end - Ty...
FAILED tests/test_volume.py::test_generate_rejects_nonpositive_multiplier - T...
============================== 6 failed in 0.09s ===============================

With the fix applied, the test passes (GREEN):

GREEN attempt 1/2 (exit 0)
============================= test session starts ==============================
platform linux -- Python 3.14.4, pytest-9.0.2, pluggy-1.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/ousama/contribute-work/OpenBMB__VoxCPM
configfile: pyproject.toml
plugins: typeguard-4.4.4
collecting ... collected 6 items

tests/test_volume.py::test_identity_multiplier_is_noop PASSED
tests/test_volume.py::test_multiplier_scales_rms_linearly rms in=0.136931 out=0.273861 ratio=2.000000
PASSED
tests/test_volume.py::test_peak_limited_to_avoid_clipping peak after 3x = 1.000000
PASSED
tests/test_volume.py::test_empty_waveform_untouched PASSED
tests/test_volume.py::test_generate_applies_multiplier_end_to_end end-to-end ratio = 2.000000
PASSED
tests/test_volume.py::test_generate_rejects_nonpositive_multiplier PASSED

============================== 6 passed in 0.08s ===============================

Full local suite

Command: python3 -m pytest tests/ -v

============================= test session starts ==============================
platform linux -- Python 3.14.4, pytest-9.0.2, pluggy-1.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/ousama/contribute-work/OpenBMB__VoxCPM
configfile: pyproject.toml
plugins: typeguard-4.4.4
collecting ... collected 51 items / 2 errors

==================================== ERRORS ====================================
____________ ERROR collecting tests/test_lora_checkpoint_loading.py ____________
ImportError while importing test module '/home/ousama/contribute-work/OpenBMB__VoxCPM/tests/test_lora_checkpoint_loading.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.14/importlib/__init__.py:88: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_lora_checkpoint_loading.py:9: in <module>
    import torch
E   ModuleNotFoundError: No module named 'torch'
__________________ ERROR collecting tests/test_model_utils.py __________________
ImportError while importing test module '/home/ousama/contribute-work/OpenBMB__VoxCPM/tests/test_model_utils.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.14/importlib/__init__.py:88: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
tests/test_model_utils.py:20: in <module>
    spec.loader.exec_module(utils)
src/voxcpm/model/utils.py:3: in <module>
    import torch
E   ModuleNotFoundError: No module named 'torch'
=========================== short test summary info ============================
ERROR tests/test_lora_checkpoint_loading.py
ERROR tests/test_model_utils.py
!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!
============================== 2 errors in 0.18s ===============================

Fix #362

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

无法控制音量及每次克隆的音色不准确

1 participant