Fix ReverbEffect

Resolve GH-88
This commit is contained in:
Ngô Xuân Minh 2020-05-04 22:32:03 +07:00 committed by GitHub
parent b39aaa9903
commit c59d0ec169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 60 deletions

View File

@ -2088,235 +2088,306 @@ cdef class ReverbEffect(BaseEffect):
@property
def density(self) -> float:
"""Density, from 0.0 to 1.0."""
return self.properties.density
@density.setter
def density(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid density: {value}')
self.properties.density = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def diffusion(self) -> float:
"""Diffusion, from 0.0 to 1.0."""
return self.properties.diffusion
@diffusion.setter
def diffusion(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid diffusion: {value}')
self.properties.diffusion = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def gain(self) -> float:
"""Gain, from 0.0 to 1.0."""
return self.properties.gain
@gain.setter
def gain(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid gain: {value}')
self.properties.gain = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def gain_hf(self) -> float:
"""High frequency gain, from 0.0 to 1.0."""
return self.properties.gain_hf
@gain_hf.setter
def gain_hf(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid high frequency gain : {value}')
self.properties.gain_hf = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def gain_lf(self) -> float:
"""Low frequency gain, from 0.0 to 1.0."""
return self.properties.gain_lf
@gain_lf.setter
def gain_lf(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid low frequency gain: {value}')
self.properties.gain_lf = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def decay_time(self) -> float:
"""Decay time, from 0.1 to 20.0."""
return self.properties.decay_time
@decay_time.setter
def decay_time(self, value: float) -> None:
if value < 0.1 or value > 20.0:
raise ValueError(f'invalid decay time: {value}')
self.properties.decay_time = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def decay_hf_ratio(self) -> float:
"""High frequency decay ratio, from 0.1 to 20.0."""
return self.properties.decay_hf_ratio
@decay_hf_ratio.setter
def decay_hf_ratio(self, value: float) -> None:
if value < 0.1 or value > 20.0:
raise ValueError(f'invalid high frequency decay ratio: {value}')
self.properties.decay_hf_ratio = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def decay_lf_ratio(self) -> float:
"""Low frequency decay ratio, from 0.1 to 20.0."""
return self.properties.decay_lf_ratio
@decay_lf_ratio.setter
def decay_lf_ratio(self, value: float) -> None:
if value < 0.1 or value > 20.0:
raise ValueError(f'invalid low frequency decay ratio: {value}')
self.properties.decay_lf_ratio = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def reflections_gain(self) -> float:
"""Reflections gain, from 0.0 to 3.16."""
return self.properties.reflections_gain
@reflections_gain.setter
def reflections_gain(self, value: float) -> None:
if value < 0.0 or value > 3.16:
raise ValueError(f'invalid reflections gain: {value}')
self.properties.reflections_gain = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def reflections_delay(self) -> float:
"""Reflections delay, from 0.0 to 0.3."""
return self.properties.reflections_delay
@reflections_delay.setter
def reflections_delay(self, value: float) -> None:
if value < 0.0 or value > 0.3:
raise ValueError(f'invalid reflections delay: {value}')
self.properties.reflections_delay = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def reflections_pan(self) -> Vector3:
"""Reflections as 3D vector of magnitude between 0 and 1."""
return self.properties.reflections_pan
@reflections_pan.setter
def reflections_pan(self, value: Vector3) -> None:
self.properties.reflections_pan[0] = value[0]
self.properties.reflections_pan[1] = value[1]
self.properties.reflections_pan[2] = value[2]
x, y, z = value
magnitude = x*x + y*y + z*z
if magnitude < 0 or magnitude > 1:
raise ValueError(f'invalid reflections pan: {value}')
self.properties.reflections_pan[0] = x
self.properties.reflections_pan[1] = y
self.properties.reflections_pan[2] = z
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def late_reverb_gain(self) -> float:
"""Late reverb gain, from 0.0 to 10.0."""
return self.properties.late_reverb_gain
@late_reverb_gain.setter
def late_reverb_gain(self, value: float) -> None:
if value < 0.0 or value > 10.0:
raise ValueError(f'invalid late reverb gain: {value}')
self.properties.late_reverb_gain = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def late_reverb_delay(self) -> float:
"""Late reverb delay, from 0.0 to 0.1."""
return self.properties.late_reverb_delay
@late_reverb_delay.setter
def late_reverb_delay(self, value: float) -> None:
if value < 0.0 or value > 0.1:
raise ValueError(f'invalid late reverb delay: {value}')
self.properties.late_reverb_delay = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def late_reverb_pan(self) -> Vector3:
"""Late reverb as 3D vector of magnitude between 0 and 1."""
return self.properties.late_reverb_pan
@late_reverb_pan.setter
def late_reverb_pan(self, value: Vector3) -> None:
self.properties.late_reverb_pan[0] = value[0]
self.properties.late_reverb_pan[1] = value[1]
self.properties.late_reverb_pan[2] = value[2]
x, y, z = value
magnitude = x*x + y*y + z*z
if magnitude < 0 or magnitude > 1:
raise ValueError(f'invalid late reverb pan: {value}')
self.properties.late_reverb_pan[0] = x
self.properties.late_reverb_pan[1] = y
self.properties.late_reverb_pan[2] = z
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def echo_time(self) -> float:
"""Echo time, from 0.075 to 0.25."""
return self.properties.echo_time
@echo_time.setter
def echo_time(self, value: float) -> None:
if value < 0.075 or value > 0.25:
raise ValueError(f'invalid echo time: {value}')
self.properties.echo_time = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def echo_depth(self) -> float:
"""Echo depth, from 0.0 to 1.0."""
return self.properties.echo_depth
@echo_depth.setter
def echo_depth(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid echo depth: {value}')
self.properties.echo_depth = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def modulation_time(self) -> float:
"""Modulation time, from 0.004 to 4.0."""
return self.properties.modulation_time
@modulation_time.setter
def modulation_time(self, value: float) -> None:
if value < 0.004 or value > 4.0:
raise ValueError(f'invalid modulation time: {value}')
self.properties.modulation_time = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def modulation_depth(self) -> float:
"""Modulation depth, from 0.0 to 1.0."""
return self.properties.modulation_depth
@modulation_depth.setter
def modulation_depth(self, value: float) -> None:
if value < 0.0 or value > 1.0:
raise ValueError(f'invalid modulation depth: {value}')
self.properties.modulation_depth = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def air_absorption_gain_hf(self) -> float:
"""High frequency air absorption gain, from 0.892 to 1.0."""
return self.properties.air_absorption_gain_hf
@air_absorption_gain_hf.setter
def air_absorption_gain_hf(self, value: float) -> None:
if value < 0.892 or value > 1.0:
raise ValueError(f'invalid high frequency air absorption gain: {value}')
self.properties.air_absorption_gain_hf = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def hf_reference(self) -> float:
"""High frequency reference, from 1000.0 to 20000.0."""
return self.properties.hf_reference
@hf_reference.setter
def hf_reference(self, value: float) -> None:
if value < 1000.0 or value > 20000.0:
raise ValueError(f'invalid high frequency reference: {value}')
self.properties.hf_reference = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def lf_reference(self) -> float:
"""Low frequency reference, from 20.0 to 1000.0."""
return self.properties.lf_reference
@lf_reference.setter
def lf_reference(self, value: float) -> None:
if value < 20.0 or value > 1000.0:
raise ValueError(f'invalid low frequency reference: {value}')
self.properties.lf_reference = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def room_rolloff_factor(self) -> float:
"""Room rolloff factor, from 0.0 to 10.0."""
return self.properties.room_rolloff_factor
@room_rolloff_factor.setter
def room_rolloff_factor(self, value: float) -> None:
if value < 0.0 or value > 10.0:
raise ValueError(f'invalid room rolloff factor: {value}')
self.properties.room_rolloff_factor = value
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)
@property
def decay_hf_limit(self) -> bool:
return self.properties.decay_hf_limit
"""High frequency decay limit."""
return bool(self.properties.decay_hf_limit)
@decay_hf_limit.setter
def decay_hf_limit(self, value: bool) -> None:
self.properties.decay_hf_limit = value
self.properties.decay_hf_limit = bool(value)
self.impl.set_reverb_properties(self.properties)
self.slot.apply_effect(self.impl)

View File

@ -20,7 +20,7 @@
"""This pytest module verifies environmental effects."""
from palace import BaseEffect, ChorusEffect, ReverbEffect, Source
from pytest import mark, raises
from pytest import raises
from fmath import isclose, allclose
@ -62,7 +62,6 @@ def test_reverb_send_auto(context):
fx.send_auto = True
@mark.xfail
def test_reverb_density(context):
"""Test ReverbEffect's property density."""
with ReverbEffect() as fx:
@ -77,7 +76,6 @@ def test_reverb_density(context):
with raises(ValueError): fx.density = -1
@mark.xfail
def test_reverb_diffusion(context):
"""Test ReverbEffect's property diffusion."""
with ReverbEffect() as fx:
@ -92,11 +90,10 @@ def test_reverb_diffusion(context):
with raises(ValueError): fx.diffusion = -1
@mark.xfail
def test_reverb_gain(context):
"""Test ReverbEffect's property gain."""
with ReverbEffect() as fx:
assert isclose(fx.gain, 0.32)
assert isclose(fx.gain, 0.3162)
fx.gain = 5/7
assert isclose(fx.gain, 5/7)
fx.gain = 0
@ -107,11 +104,10 @@ def test_reverb_gain(context):
with raises(ValueError): fx.gain = -1
@mark.xfail
def test_reverb_gain_hf(context):
"""Test ReverbEffect's property gain_hf."""
with ReverbEffect() as fx:
assert isclose(fx.gain_hf, 0.89)
assert isclose(fx.gain_hf, 0.8913)
fx.gain_hf = 5/7
assert isclose(fx.gain_hf, 5/7)
fx.gain_hf = 0
@ -122,11 +118,10 @@ def test_reverb_gain_hf(context):
with raises(ValueError): fx.gain_hf = -1
@mark.xfail
def test_reverb_gain_lf(context):
"""Test ReverbEffect's property gain_lf."""
with ReverbEffect() as fx:
assert fx.gain_lf == 0
assert fx.gain_lf == 1
fx.gain_lf = 5/7
assert isclose(fx.gain_lf, 5/7)
fx.gain_lf = 0
@ -137,7 +132,6 @@ def test_reverb_gain_lf(context):
with raises(ValueError): fx.gain_lf = -1
@mark.xfail
def test_reverb_decay_time(context):
"""Test ReverbEffect's property decay_time."""
with ReverbEffect() as fx:
@ -152,7 +146,6 @@ def test_reverb_decay_time(context):
with raises(ValueError): fx.decay_time = -1
@mark.xfail
def test_reverb_decay_hf_ratio(context):
"""Test ReverbEffect's property decay_hf_ratio."""
with ReverbEffect() as fx:
@ -163,11 +156,10 @@ def test_reverb_decay_hf_ratio(context):
assert isclose(fx.decay_hf_ratio, 0.1)
fx.decay_hf_ratio = 2
assert fx.decay_hf_ratio == 2
with raises(ValueError): fx.decay_hf_ratio = 3
with raises(ValueError): fx.decay_hf_ratio = 21
with raises(ValueError): fx.decay_hf_ratio = -1
@mark.xfail
def test_reverb_decay_lf_ratio(context):
"""Test ReverbEffect's property decay_lf_ratio."""
with ReverbEffect() as fx:
@ -178,11 +170,10 @@ def test_reverb_decay_lf_ratio(context):
assert isclose(fx.decay_lf_ratio, 0.1)
fx.decay_lf_ratio = 2
assert fx.decay_lf_ratio == 2
with raises(ValueError): fx.decay_lf_ratio = 3
with raises(ValueError): fx.decay_lf_ratio = 21
with raises(ValueError): fx.decay_lf_ratio = -1
@mark.xfail
def test_reverb_reflections_gain(context):
"""Test ReverbEffect's property reflections_gain."""
with ReverbEffect() as fx:
@ -197,7 +188,6 @@ def test_reverb_reflections_gain(context):
with raises(ValueError): fx.reflections_gain = -1
@mark.xfail
def test_reverb_reflections_delay(context):
"""Test ReverbEffect's property reflections_delay."""
with ReverbEffect() as fx:
@ -210,15 +200,13 @@ def test_reverb_reflections_delay(context):
with raises(ValueError): fx.reflections_delay = -1
@mark.xfail
def test_reverb_reflections_pan(context):
"""Test ReverbEffect's property reflections_pan."""
with ReverbEffect() as fx:
assert allclose(fx.reflections_pan, (0, 0, 0))
fx.reflections_pan = 5/7, -69/420, 6/9
assert allclose(fx.reflections_pan, (5/7, -69/420, 6/9))
fx.reflections_pan = 1, 1, 1
assert allclose(fx.reflections_pan, (1, 1, 1))
with raises(ValueError): fx.reflections_pan = 1, 1, 1
with raises(ValueError): fx.reflections_pan = 0, 0, 2
with raises(ValueError): fx.reflections_pan = 0, 2, 0
with raises(ValueError): fx.reflections_pan = 2, 0, 0
@ -227,11 +215,10 @@ def test_reverb_reflections_pan(context):
with raises(ValueError): fx.reflections_pan = -2, 0, 0
@mark.xfail
def test_reverb_late_reverb_gain(context):
"""Test ReverbEffect's property late_reverb_gain."""
with ReverbEffect() as fx:
assert isclose(fx.late_reverb_gain, 1.26)
assert isclose(fx.late_reverb_gain, 1.2589)
fx.late_reverb_gain = 5/7
assert isclose(fx.late_reverb_gain, 5/7)
fx.late_reverb_gain = 0
@ -242,7 +229,6 @@ def test_reverb_late_reverb_gain(context):
with raises(ValueError): fx.late_reverb_gain = -1
@mark.xfail
def test_reverb_late_reverb_delay(context):
"""Test ReverbEffect's property late_reverb_delay."""
with ReverbEffect() as fx:
@ -257,15 +243,13 @@ def test_reverb_late_reverb_delay(context):
with raises(ValueError): fx.late_reverb_delay = -1
@mark.xfail
def test_reverb_late_reverb_pan(context):
"""Test ReverbEffect's property late_reverb_pan."""
with ReverbEffect() as fx:
assert allclose(fx.late_reverb_pan, (0, 0, 0))
fx.late_reverb_pan = 5/7, -69/420, 6/9
assert allclose(fx.late_reverb_pan, (5/7, -69/420, 6/9))
fx.late_reverb_pan = 1, 1, 1
assert allclose(fx.late_reverb_pan, (1, 1, 1))
with raises(ValueError): fx.late_reverb_pan = 1, 1, 1
with raises(ValueError): fx.late_reverb_pan = 0, 0, 2
with raises(ValueError): fx.late_reverb_pan = 0, 2, 0
with raises(ValueError): fx.late_reverb_pan = 2, 0, 0
@ -274,7 +258,6 @@ def test_reverb_late_reverb_pan(context):
with raises(ValueError): fx.late_reverb_pan = -2, 0, 0
@mark.xfail
def test_reverb_echo_time(context):
"""Test ReverbEffect's property echo_time."""
with ReverbEffect() as fx:
@ -287,7 +270,6 @@ def test_reverb_echo_time(context):
with raises(ValueError): fx.echo_time = 0.5
@mark.xfail
def test_reverb_echo_depth(context):
"""Test ReverbEffect's property echo_depth."""
with ReverbEffect() as fx:
@ -302,11 +284,10 @@ def test_reverb_echo_depth(context):
with raises(ValueError): fx.echo_depth = -1
@mark.xfail
def test_reverb_modulation_time(context):
"""Test ReverbEffect's property modulation_time."""
with ReverbEffect() as fx:
assert isclose(0.25)
assert isclose(fx.modulation_time, 0.25)
fx.modulation_time = 5/7
assert isclose(fx.modulation_time, 5/7)
fx.modulation_time = 0.04
@ -317,7 +298,6 @@ def test_reverb_modulation_time(context):
with raises(ValueError): fx.modulation_time = 0
@mark.xfail
def test_reverb_modulation_depth(context):
"""Test ReverbEffect's property modulation_depth."""
with ReverbEffect() as fx:
@ -332,22 +312,20 @@ def test_reverb_modulation_depth(context):
with raises(ValueError): fx.modulation_depth = -1
@mark.xfail
def test_reverb_air_absorption_gain_hf(context):
"""Test ReverbEffect's property air_absorption_gain_hf."""
with ReverbEffect() as fx:
assert isclose(fx.air_absorption_gain_hf, 0.994)
assert isclose(fx.air_absorption_gain_hf, 0.9943)
fx.air_absorption_gain_hf = 0.999
assert isclose(fx.air_absorption_gain_hf, 0.999)
fx.air_absorption_gain_hf = 0.892
assert isclose(fx.air_absorption_gain_hf, 892)
assert isclose(fx.air_absorption_gain_hf, 0.892)
fx.air_absorption_gain_hf = 1
assert fx.air_absorption_gain_hf == 1
with raises(ValueError): fx.air_absorption_gain_hf = 7/5
with raises(ValueError): fx.air_absorption_gain_hf = 0.5
@mark.xfail
def test_reverb_hf_reference(context):
"""Test ReverbEffect's property hf_reference."""
with ReverbEffect() as fx:
@ -362,7 +340,6 @@ def test_reverb_hf_reference(context):
with raises(ValueError): fx.hf_reference = 999
@mark.xfail
def test_reverb_lf_reference(context):
"""Test ReverbEffect's property lf_reference."""
with ReverbEffect() as fx:
@ -377,7 +354,6 @@ def test_reverb_lf_reference(context):
with raises(ValueError): fx.lf_reference = 1001
@mark.xfail
def test_reverb_room_rolloff_factor(context):
"""Test ReverbEffect's property room_rolloff_factor."""
with ReverbEffect() as fx:
@ -395,11 +371,11 @@ def test_reverb_room_rolloff_factor(context):
def test_reverb_decay_hf_limit(context):
"""Test ReverbEffect's property decay_hf_limit."""
with ReverbEffect() as fx:
assert fx.decay_hf_limit
assert fx.decay_hf_limit is True
fx.decay_hf_limit = False
assert not fx.decay_hf_limit
assert fx.decay_hf_limit is False
fx.decay_hf_limit = True
assert fx.decay_hf_limit
assert fx.decay_hf_limit is True
def test_chorus_waveform(context):
@ -425,19 +401,6 @@ def test_chorus_phase(context):
with raises(ValueError): fx.phase = -181
@mark.xfail
def test_chorus_rate(context):
"""Test ChorusEffect's property rate."""
with ChorusEffect() as fx:
assert isclose(fx.rate, 1.1)
fx.rate = 0
assert fx.rate == 0
fx.rate = 10
assert fx.rate == 10
with raises(ValueError): fx.rate = 11
with raises(ValueError): fx.rate = -1
def test_chorus_depth(context):
"""Test ChorusEffect's property depth."""
with ChorusEffect() as fx: