2019-01-08 22:06:06 +00:00
|
|
|
import hypothesis.strategies as hs
|
2018-08-24 08:23:20 +00:00
|
|
|
import numpy as np
|
2018-08-24 06:51:26 +00:00
|
|
|
import pytest
|
2018-11-17 09:13:46 +00:00
|
|
|
from hypothesis import given
|
2018-08-24 08:23:20 +00:00
|
|
|
from pytest_mock import MockFixture
|
2018-08-24 06:51:26 +00:00
|
|
|
|
2018-12-20 10:31:55 +00:00
|
|
|
import corrscope.channel
|
|
|
|
import corrscope.corrscope
|
|
|
|
from corrscope.channel import ChannelConfig, Channel
|
|
|
|
from corrscope.corrscope import default_config, CorrScope, BenchmarkMode, Arguments
|
|
|
|
from corrscope.triggers import NullTriggerConfig
|
2018-08-24 08:23:20 +00:00
|
|
|
|
2018-12-06 20:11:39 +00:00
|
|
|
|
2018-11-17 09:13:46 +00:00
|
|
|
positive = hs.integers(min_value=1, max_value=100)
|
2018-12-06 20:11:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
@given(
|
|
|
|
# Channel
|
2019-01-08 22:06:06 +00:00
|
|
|
c_trigger_width=positive,
|
|
|
|
c_render_width=positive,
|
2018-12-06 20:11:39 +00:00
|
|
|
# Global
|
2019-01-08 22:06:06 +00:00
|
|
|
trigger_ms=positive,
|
|
|
|
render_ms=positive,
|
|
|
|
tsub=positive,
|
|
|
|
rsub=positive,
|
2018-12-06 20:11:39 +00:00
|
|
|
)
|
|
|
|
def test_config_channel_width_stride(
|
|
|
|
# Channel
|
2019-01-08 22:06:06 +00:00
|
|
|
c_trigger_width: int,
|
|
|
|
c_render_width: int,
|
2018-12-06 20:11:39 +00:00
|
|
|
# Global
|
2019-01-08 22:06:06 +00:00
|
|
|
trigger_ms: int,
|
|
|
|
render_ms: int,
|
|
|
|
tsub: int,
|
|
|
|
rsub: int,
|
2018-12-06 20:11:39 +00:00
|
|
|
mocker: MockFixture,
|
2018-08-24 06:51:26 +00:00
|
|
|
):
|
2018-12-06 20:11:39 +00:00
|
|
|
""" (Tautologically) verify:
|
|
|
|
- channel. r_samp (given cfg)
|
2019-01-08 22:06:06 +00:00
|
|
|
- channel.t/r_stride (given cfg.*_subsampling/*_width)
|
2018-12-06 20:11:39 +00:00
|
|
|
- trigger._tsamp, _stride
|
|
|
|
- renderer's method calls(samp, stride)
|
|
|
|
"""
|
2018-08-24 06:51:26 +00:00
|
|
|
|
2018-11-17 09:13:46 +00:00
|
|
|
# region setup test variables
|
2019-01-03 08:57:30 +00:00
|
|
|
corrscope.corrscope.PRINT_TIMESTAMP = False # Cleanup Hypothesis testing logs
|
2018-08-24 08:23:20 +00:00
|
|
|
|
2019-01-03 08:57:30 +00:00
|
|
|
Wave = mocker.patch.object(corrscope.channel, "Wave")
|
2018-08-24 08:23:20 +00:00
|
|
|
wave = Wave.return_value
|
|
|
|
|
2019-01-08 05:13:02 +00:00
|
|
|
def get_around(sample: int, return_nsamp: int, stride: int):
|
|
|
|
return np.zeros(return_nsamp)
|
2018-08-24 08:23:20 +00:00
|
|
|
|
|
|
|
wave.get_around.side_effect = get_around
|
2019-01-08 22:15:18 +00:00
|
|
|
wave.with_flatten.return_value = wave
|
2018-08-24 08:23:20 +00:00
|
|
|
wave.nsamp = 10000
|
|
|
|
wave.smp_s = 48000
|
|
|
|
|
2018-08-24 06:51:26 +00:00
|
|
|
ccfg = ChannelConfig(
|
2019-01-03 08:57:30 +00:00
|
|
|
"tests/sine440.wav", trigger_width=c_trigger_width, render_width=c_render_width
|
2018-08-24 06:51:26 +00:00
|
|
|
)
|
2019-01-03 08:57:30 +00:00
|
|
|
|
2018-12-06 20:11:39 +00:00
|
|
|
def get_cfg():
|
|
|
|
return default_config(
|
|
|
|
trigger_ms=trigger_ms,
|
|
|
|
render_ms=render_ms,
|
|
|
|
trigger_subsampling=tsub,
|
|
|
|
render_subsampling=rsub,
|
|
|
|
channels=[ccfg],
|
|
|
|
trigger=NullTriggerConfig(),
|
2019-01-03 08:57:30 +00:00
|
|
|
benchmark_mode=BenchmarkMode.OUTPUT,
|
2018-12-06 20:11:39 +00:00
|
|
|
)
|
2019-01-03 08:57:30 +00:00
|
|
|
|
2018-11-17 09:13:46 +00:00
|
|
|
# endregion
|
2018-08-24 06:51:26 +00:00
|
|
|
|
2018-12-06 20:11:39 +00:00
|
|
|
cfg = get_cfg()
|
|
|
|
channel = Channel(ccfg, cfg)
|
|
|
|
|
|
|
|
# Ensure cfg.width_ms etc. are correct
|
2019-01-08 22:06:06 +00:00
|
|
|
assert cfg.trigger_ms == trigger_ms
|
|
|
|
assert cfg.render_ms == render_ms
|
2018-12-06 20:11:39 +00:00
|
|
|
|
2018-08-26 01:51:01 +00:00
|
|
|
# Ensure channel.window_samp, trigger_subsampling, render_subsampling are correct.
|
2018-12-06 20:11:39 +00:00
|
|
|
def ideal_samp(width_ms, sub):
|
|
|
|
width_s = width_ms / 1000
|
2019-01-08 22:15:18 +00:00
|
|
|
return pytest.approx(
|
|
|
|
round(width_s * channel.trigger_wave.smp_s / sub), rel=1e-6
|
|
|
|
)
|
2018-11-17 09:13:46 +00:00
|
|
|
|
2018-12-06 20:11:39 +00:00
|
|
|
ideal_tsamp = ideal_samp(cfg.trigger_ms, tsub)
|
|
|
|
ideal_rsamp = ideal_samp(cfg.render_ms, rsub)
|
2018-11-17 09:13:46 +00:00
|
|
|
assert channel.render_samp == ideal_rsamp
|
2018-08-24 08:23:20 +00:00
|
|
|
|
2019-01-08 22:06:06 +00:00
|
|
|
assert channel.trigger_stride == tsub * c_trigger_width
|
|
|
|
assert channel.render_stride == rsub * c_render_width
|
2018-08-24 06:51:26 +00:00
|
|
|
|
2018-11-17 09:13:46 +00:00
|
|
|
## Ensure trigger uses channel.window_samp and trigger_stride.
|
2018-08-24 08:23:20 +00:00
|
|
|
trigger = channel.trigger
|
2018-11-17 09:13:46 +00:00
|
|
|
assert trigger._tsamp == ideal_tsamp
|
2018-11-17 23:47:32 +00:00
|
|
|
assert trigger._stride == channel.trigger_stride
|
2018-08-24 08:23:20 +00:00
|
|
|
|
2018-12-20 10:31:55 +00:00
|
|
|
## Ensure corrscope calls render using channel.render_samp and render_stride.
|
2019-01-03 08:57:30 +00:00
|
|
|
corr = CorrScope(cfg, Arguments(cfg_dir=".", outputs=[]))
|
|
|
|
renderer = mocker.patch.object(CorrScope, "_load_renderer").return_value
|
2018-12-20 10:31:55 +00:00
|
|
|
corr.play()
|
2018-08-24 08:23:20 +00:00
|
|
|
|
2018-11-17 09:13:46 +00:00
|
|
|
# Only render (not NullTrigger) calls wave.get_around().
|
2019-01-08 05:13:02 +00:00
|
|
|
(_sample, _return_nsamp, _subsampling), kwargs = wave.get_around.call_args
|
|
|
|
assert _return_nsamp == channel.render_samp
|
2018-11-17 09:13:46 +00:00
|
|
|
assert _subsampling == channel.render_stride
|
2018-08-24 08:23:20 +00:00
|
|
|
|
|
|
|
# Inspect arguments to renderer.render_frame()
|
|
|
|
# datas: List[np.ndarray]
|
|
|
|
(datas,), kwargs = renderer.render_frame.call_args
|
|
|
|
render_data = datas[0]
|
2018-11-17 09:13:46 +00:00
|
|
|
assert len(render_data) == channel.render_samp
|
2018-08-24 06:51:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
# line_color is tested in test_renderer.py
|
|
|
|
# todo test ChannelConfig.ampl_ratio
|