Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lddecode/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2651,6 +2651,7 @@ def downscale(
audio=0,
final=False,
lastfieldwritten=None,
shift=0
):
if lineinfo is None:
lineinfo = self.linelocs
Expand Down Expand Up @@ -2717,7 +2718,8 @@ def downscale(
self.rf.downscale_sinc_lut,
self.lineoffset,
outwidth,
wow_level_adjust_smoothing=self.wow_level_adjust_smoothing
wow_level_adjust_smoothing=self.wow_level_adjust_smoothing,
shift=shift
)

if self.rf.decode_digital_audio:
Expand Down
5 changes: 3 additions & 2 deletions lddecode/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def scale(buf, begin, end, tgtlen, mult=1):


@njit(nogil=True, fastmath=True)
def scale_field(buf, dsout, interpolated_pixel_locs, wowfactors, sinc_lut, lineoffset, outwidth, wow_level_adjust_smoothing = 0, level_adjust_threshold = 15):
def scale_field(buf, dsout, interpolated_pixel_locs, wowfactors, sinc_lut, lineoffset, outwidth, wow_level_adjust_smoothing = 0, level_adjust_threshold = 15, shift=0.0):
# average out any unusual spikes in wow that happen on a per line basis
# this indicates an hsync tbc error vs. being normal wow from playback speed variations
# in this case for level adjusting we just want to fallback to the average wow to avoid a bright or dark line
Expand Down Expand Up @@ -175,7 +175,8 @@ def scale_field(buf, dsout, interpolated_pixel_locs, wowfactors, sinc_lut, lineo
level_adjust = level_adjusts[i]

# reconstructs the waveform at the proper fractional sample position, undoing wow-induced timing variations
coord = np.float32(interpolated_pixel_locs[i])
# Adding the positive shift pulls future (late) samples backward into alignment.
coord = np.float32(interpolated_pixel_locs[i] + shift)
coord_int = int(coord)

# fractional phase
Expand Down
38 changes: 9 additions & 29 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ def test_sync(filename, num_pulses=None, blank_approx=None, sync_approx=None):
ldd.logger.info("test")

# process.VHSDecode("infile", "outfile", ,inputfreq=samplerate_mhz, system="PAL", tape_format="VHS")
rf_options = {}
rf_options["level_detect_divisor"] = 2
rfdecoder = process.VHSRFDecode(
inputfreq=samplerate_mhz, system="PAL", tape_format="VHS", rf_options=rf_options
inputfreq=samplerate_mhz, system="PAL", tape_format="VHS"
)

demod_05_data = np.loadtxt(filename)
Expand All @@ -107,12 +105,13 @@ def test_sync(filename, num_pulses=None, blank_approx=None, sync_approx=None):

field = FieldPALVHS(rfdecoder, data_stub)

pulses = rfdecoder.resync.get_pulses(field)
pulses = field.get_pulses()

if num_pulses:
assert len(pulses) == num_pulses

measured_sync, measured_blank = rfdecoder.resync._field_state.pull_levels()
measured_sync = field.sync_tip_level
measured_blank = field.blanking_level

if blank_approx:
assert math.isclose(measured_blank, blank_approx)
Expand All @@ -122,20 +121,6 @@ def test_sync(filename, num_pulses=None, blank_approx=None, sync_approx=None):
return True


def test_find_pulses(filename, num_pulses):
from vhsdecode.addons.resync import _findpulses_numba_raw

demod_05_data = np.loadtxt(filename)

# Just using some pre-tested values for now for optimizing function, many need changes later.
starts, lengths = _findpulses_numba_raw(demod_05_data, 3954307.8, 11.625, 1588.125)

assert len(starts) == num_pulses
assert len(lengths) == num_pulses
assert starts[200] == 495955
assert lengths[200] == 177


class SyncTest(unittest.TestCase):
def test_sync_pal_good(self):
blank = 4130000
Expand All @@ -151,9 +136,6 @@ def test_sync_pal_noisy(self):
print("pal noisy")
test_sync("PAL_NOISY.txt.gz", blank_approx=blank, sync_approx=sync)

def test_find_pulses(self):
test_find_pulses("PAL_GOOD.txt.gz", 458)


class ZCTest(unittest.TestCase):
def test_calczc(self):
Expand Down Expand Up @@ -227,10 +209,8 @@ def test_1(self):
ldd.logger.info("test")
demod_05_data = np.loadtxt("PAL_GOOD.txt.gz")

rf_options = {}
rf_options["level_detect_divisor"] = 2
rfdecoder = process.VHSRFDecode(
inputfreq=40, system="PAL", tape_format="VHS", rf_options=rf_options
inputfreq=40, system="PAL", tape_format="VHS"
)

data_stub = {}
Expand All @@ -241,11 +221,11 @@ def test_1(self):

field = FieldPALVHS(rfdecoder, data_stub)

_ = rfdecoder.resync.get_pulses(field)
blank_level = rfdecoder.resync._field_state._blanklevels.current()
sync_level = rfdecoder.resync._field_state._synclevels.current()
print("blank level: ", blank_level)
_ = field.get_pulses(True)
sync_level = field.sync_tip_level
blank_level = field.blanking_level
print("sync level: ", sync_level)
print("blank level: ", blank_level)


if __name__ == "__main__":
Expand Down
1 change: 0 additions & 1 deletion tests/run_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ mutation _export_raw_tbc "vhs_pal" --export_raw_tbc
mutation _fallback_vsync_ntsc "svhs_et_ntsc" --fallback_vsync
mutation _fm_audio_notch "vhs_ntsc" --fm_audio_notch 10
mutation _ire0_adjust "vhs_ntsc" --ire0_adjust
mutation _level_detect_div5 "svhs_et_ntsc" --level_detect_divisor 5
mutation _nld "vhs_ntsc" --nld
mutation _notch_ntsc "vhs_ntsc" --notch 3.58
mutation _notch_pal "vhs_pal" --notch 4.43
Expand Down
34 changes: 10 additions & 24 deletions tests/unit/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
import lddecode.core as ldd
import vhsdecode.process as process
from vhsdecode.field import FieldPALVHS
from vhsdecode.addons.resync import _findpulses_numba_raw


@pytest.fixture
def pal_rfdecoder():
ldd.logger = logging.getLogger("test")
ldd.logger.setLevel(5)
rf_options = {"level_detect_divisor": 2}
return process.VHSRFDecode(
inputfreq=40, system="PAL", tape_format="VHS", rf_options=rf_options
inputfreq=40, system="PAL", tape_format="VHS"
)


Expand All @@ -35,35 +32,24 @@ def _make_field(rfdecoder, filename):
class TestSyncPAL:
def test_sync_pal_good(self, pal_rfdecoder, data_dir):
field = _make_field(pal_rfdecoder, data_dir / "PAL_GOOD.txt.gz")
pulses = pal_rfdecoder.resync.get_pulses(field)
pulses = field.get_pulses()
assert len(pulses) == 458
measured_sync, measured_blank = pal_rfdecoder.resync._field_state.pull_levels()
measured_sync, measured_blank = field.sync_tip_level, field.blanking_level
assert math.isclose(measured_blank, 4133579.15, rel_tol=1e-3)
assert math.isclose(measured_sync, 3840000, rel_tol=1e-3)

def test_sync_pal_noisy(self, pal_rfdecoder, data_dir):
field = _make_field(pal_rfdecoder, data_dir / "PAL_NOISY.txt.gz")
pal_rfdecoder.resync.get_pulses(field)
measured_sync, measured_blank = pal_rfdecoder.resync._field_state.pull_levels()
assert math.isclose(measured_blank, 4130360.76, rel_tol=1e-3)
assert math.isclose(measured_sync, 3800000, rel_tol=1e-3)


class TestFindPulses:
def test_find_pulses_pal_good(self, data_dir):
demod_05_data = np.loadtxt(data_dir / "PAL_GOOD.txt.gz")
starts, lengths = _findpulses_numba_raw(demod_05_data, 3954307.8, 11.625, 1588.125)
assert len(starts) == 458
assert len(lengths) == 458
assert starts[200] == 495955
assert lengths[200] == 177
_ = field.get_pulses()
measured_sync, measured_blank = field.sync_tip_level, field.blanking_level
assert math.isclose(measured_blank, 4137794.68, rel_tol=1e-3)
assert math.isclose(measured_sync, 3795981.06, rel_tol=1e-3)


class TestLevelDetect:
def test_level_detect_pal_good(self, pal_rfdecoder, data_dir):
field = _make_field(pal_rfdecoder, data_dir / "PAL_GOOD.txt.gz")
pal_rfdecoder.resync.get_pulses(field)
blank_level = pal_rfdecoder.resync._field_state._blanklevels.current()
sync_level = pal_rfdecoder.resync._field_state._synclevels.current()
assert blank_level is not None
_ = field.get_pulses(True)
sync_level, blank_level = field.sync_tip_level, field.blanking_level
assert sync_level is not None
assert blank_level is not None
2 changes: 1 addition & 1 deletion vhsdecode/addons/chromaAFC.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from numpy.fft import rfft, rfftfreq
import lddecode.core as ldd
from scipy.signal import argrelextrema
from vhsdecode.linear_filter import FiltersClass
from vhsdecode.rust_utils import sosfiltfilt_rust
from vhsdecode.linear_filter import FiltersClass

twopi = 2 * np.pi

Expand Down
Loading
Loading