4949# a collaborative work.
5050# Breaking: JSON & metadata (`liq_sustained_ending`)
5151# 2024-06-14 Moonbase59 - Add mutagen vserion to `-V`/`--version`.
52+ # 2024-06-15 Moonbase59 - Catch IndexError in sustained calculation if we are
53+ # already at the end of the track.
5254#
5355# Originally based on an idea and some code by John Warburton (@Warblefly):
5456# https://github.com/Warblefly/TrackBoundaries
5557# Some collaborative work with RM-FM (@RM-FM): Sustained ending analysis.
5658
5759__author__ = 'Matthias C. Hormann'
58- __version__ = '4.0.0 '
60+ __version__ = '4.0.1 '
5961
6062import os
6163import sys
@@ -662,14 +664,16 @@ def analyse(
662664 # Split into left & right part, use avg momentary loudness of each
663665 def slope (elements ):
664666 l = len (elements )
667+ if l < 1 :
668+ raise ValueError ("need at least one measure point to calculate" )
665669 l2 = l // 2
666670 p1 = elements [:l2 ] if l >= 2 else elements [:]
667671 # leave out midpoint if we have an odd number of elements
668672 # this is mainly for sliding window techniques
669673 # and guarantees both halves are the same size
670674 p2 = elements [l2 + l % 2 :] if l >= 2 else elements [:]
675+ eprint (l , l2 , len (p1 ), len (p2 ))
671676 t = elements [l2 ][0 ] # time of midpoint
672- # eprint(l, l2, len(p1), len(p2))
673677 y1 = sum (i [1 ] for i in p1 ) # sum momentary loudness
674678 y2 = sum (i [1 ] for i in p2 ) # sum momentary loudness
675679 if l2 > 0 :
@@ -695,22 +699,24 @@ def analyse(
695699 sustained = False
696700 start_next_time_sustained = 0.0
697701 # eprint(f"Index: {start_next_idx}–{end}, Silence: {silence_level:.2f} LUFS, Start Next Level: {start_next_level:.2f} LUFS")
698- # start_next_time = sliding_window(measure[start_next_idx:end], 21)
699- time , lufs , m , degrees , lufs_ratio_pct , max_lufs = slope (
700- measure [start_next_idx :end ])
701- # eprint(f"Slope m={m:.2f}, {degrees:.2f}°, LUFS Ratio Left:Right {lufs_ratio_pct:.2f}%")
702- if lufs_ratio_pct < drop :
703- sustained = True
704- start_next_level = loudness + overlay + extra
705- # eprint(f"Sustained; Recalc with {start_next_level} LUFS")
706- start_next_time_sustained = 0.0
707- for i in reversed (range (start , end )):
708- if measure [i ][1 ] > start_next_level :
709- start_next_time_sustained = measure [i ][0 ]
710- break
711- start_next_time_sustained = max (
712- start_next_time_sustained ,
713- cue_out_time - start_next_time_sustained )
702+ # Calculation can only be done if we have at least one measure point.
703+ # We don’t if we’re already at the end.
704+ if range (start_next_idx , end ):
705+ time , lufs , m , degrees , lufs_ratio_pct , max_lufs = slope (
706+ measure [start_next_idx :end ])
707+ # eprint(f"Slope m={m:.2f}, {degrees:.2f}°, LUFS Ratio Left:Right {lufs_ratio_pct:.2f}%")
708+ if lufs_ratio_pct < drop :
709+ sustained = True
710+ start_next_level = loudness + overlay + extra
711+ # eprint(f"Sustained; Recalc with {start_next_level} LUFS")
712+ start_next_time_sustained = 0.0
713+ for i in reversed (range (start , end )):
714+ if measure [i ][1 ] > start_next_level :
715+ start_next_time_sustained = measure [i ][0 ]
716+ break
717+ start_next_time_sustained = max (
718+ start_next_time_sustained ,
719+ cue_out_time - start_next_time_sustained )
714720
715721 # We want to keep songs with a long fade-out intact, so if the calculated
716722 # overlap is longer than the "longtail_seconds" time, we check again, by reducing
0 commit comments