From a3c0cb70d76599eab66b20cdf57ef85fe35f6e46 Mon Sep 17 00:00:00 2001 From: Moonbase59 Date: Sat, 15 Jun 2024 08:48:59 +0200 Subject: [PATCH] =?UTF-8?q?v4.0.1=20=E2=80=93=20Bug=20fix:=20Catch=20index?= =?UTF-8?q?=20error=20in=20sustained=20ending=20calculation=20if=20we?= =?UTF-8?q?=E2=80=99re=20already=20at=20the=20end=20of=20the=20track.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +++++++ autocue.cue_file.liq | 3 ++- cue_file | 42 ++++++++++++++++++++++----------------- test_autocue.cue_file.liq | 2 +- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29dab1c..4e96de6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # autocue changelog +### 2024-06-15 - v4.0.1 + +- **Bug fix:** Catch index error in sustained ending calculation if we’re already at the end of the track. This could happen in very rare cases, if no earlier overlay start than the end of the track could be found. +- Added song that exposes this situation to the test set: + - Camel - The Great Marsh + + ### 2024-06-14 - v4.0.0 #### New features diff --git a/autocue.cue_file.liq b/autocue.cue_file.liq index 196561e..f564f37 100644 --- a/autocue.cue_file.liq +++ b/autocue.cue_file.liq @@ -33,6 +33,7 @@ # 2024-06-14 - Moonbase59 - Add external `cue_file` version check and a # `check_autocue_setup` function to be used after # the user-defined settings. +# 2024-06-15 - Moonbase59 - v4.0.1 - Sync with cue_file version # Lots of debugging output for AzuraCast in this, will be removed eventually. @@ -46,7 +47,7 @@ let settings.autocue.cue_file.version = settings.make( description= "Software version of autocue.cue_file. Should coincide with `cue_file`.", - "4.0.0" + "4.0.1" ) # Internal only! Not a user setting. diff --git a/cue_file b/cue_file index 3be4088..2438cda 100755 --- a/cue_file +++ b/cue_file @@ -49,13 +49,15 @@ # a collaborative work. # Breaking: JSON & metadata (`liq_sustained_ending`) # 2024-06-14 Moonbase59 - Add mutagen vserion to `-V`/`--version`. +# 2024-06-15 Moonbase59 - Catch IndexError in sustained calculation if we are +# already at the end of the track. # # Originally based on an idea and some code by John Warburton (@Warblefly): # https://github.com/Warblefly/TrackBoundaries # Some collaborative work with RM-FM (@RM-FM): Sustained ending analysis. __author__ = 'Matthias C. Hormann' -__version__ = '4.0.0' +__version__ = '4.0.1' import os import sys @@ -662,14 +664,16 @@ def analyse( # Split into left & right part, use avg momentary loudness of each def slope(elements): l = len(elements) + if l < 1: + raise ValueError("need at least one measure point to calculate") l2 = l // 2 p1 = elements[:l2] if l >= 2 else elements[:] # leave out midpoint if we have an odd number of elements # this is mainly for sliding window techniques # and guarantees both halves are the same size p2 = elements[l2 + l % 2:] if l >= 2 else elements[:] + eprint(l, l2, len(p1), len(p2)) t = elements[l2][0] # time of midpoint - # eprint(l, l2, len(p1), len(p2)) y1 = sum(i[1] for i in p1) # sum momentary loudness y2 = sum(i[1] for i in p2) # sum momentary loudness if l2 > 0: @@ -695,22 +699,24 @@ def analyse( sustained = False start_next_time_sustained = 0.0 # eprint(f"Index: {start_next_idx}–{end}, Silence: {silence_level:.2f} LUFS, Start Next Level: {start_next_level:.2f} LUFS") - # start_next_time = sliding_window(measure[start_next_idx:end], 21) - time, lufs, m, degrees, lufs_ratio_pct, max_lufs = slope( - measure[start_next_idx:end]) - # eprint(f"Slope m={m:.2f}, {degrees:.2f}°, LUFS Ratio Left:Right {lufs_ratio_pct:.2f}%") - if lufs_ratio_pct < drop: - sustained = True - start_next_level = loudness + overlay + extra - # eprint(f"Sustained; Recalc with {start_next_level} LUFS") - start_next_time_sustained = 0.0 - for i in reversed(range(start, end)): - if measure[i][1] > start_next_level: - start_next_time_sustained = measure[i][0] - break - start_next_time_sustained = max( - start_next_time_sustained, - cue_out_time - start_next_time_sustained) + # Calculation can only be done if we have at least one measure point. + # We don’t if we’re already at the end. + if range(start_next_idx, end): + time, lufs, m, degrees, lufs_ratio_pct, max_lufs = slope( + measure[start_next_idx:end]) + # eprint(f"Slope m={m:.2f}, {degrees:.2f}°, LUFS Ratio Left:Right {lufs_ratio_pct:.2f}%") + if lufs_ratio_pct < drop: + sustained = True + start_next_level = loudness + overlay + extra + # eprint(f"Sustained; Recalc with {start_next_level} LUFS") + start_next_time_sustained = 0.0 + for i in reversed(range(start, end)): + if measure[i][1] > start_next_level: + start_next_time_sustained = measure[i][0] + break + start_next_time_sustained = max( + start_next_time_sustained, + cue_out_time - start_next_time_sustained) # We want to keep songs with a long fade-out intact, so if the calculated # overlap is longer than the "longtail_seconds" time, we check again, by reducing diff --git a/test_autocue.cue_file.liq b/test_autocue.cue_file.liq index 80baf8e..6a112ff 100644 --- a/test_autocue.cue_file.liq +++ b/test_autocue.cue_file.liq @@ -52,7 +52,7 @@ settings.autocue.cue_file.nice := true # Linux/MacOS only! # Check Autocue setup, print result, shutdown if problems # The check results will also be in the log. # Returns a bool: true=ok, false=error. We ignore that here. -# set `print=true` for standalone scripts, `false` for AzuraCast +# Set `print=true` for standalone scripts, `false` for AzuraCast. ignore(check_autocue_setup(shutdown=true, print=true)) # `enable_autocue_metadata()` will autocue ALL files Liquidsoap processes.