# -*- coding: utf-8 -*-
|
from typing import List, Optional, Tuple
|
|
|
def smooth_scores(time_scores: List[Tuple[float, float]], window: int = 3) -> List[Tuple[float, float]]:
|
if len(time_scores) <= 1 or window <= 1:
|
return time_scores
|
half = window // 2
|
smoothed = []
|
for i, (t, _) in enumerate(time_scores):
|
lo = max(0, i - half)
|
hi = min(len(time_scores), i + half + 1)
|
avg = sum(s for _, s in time_scores[lo:hi]) / (hi - lo)
|
smoothed.append((t, avg))
|
return smoothed
|
|
|
def find_peak(
|
time_scores: List[Tuple[float, float]],
|
min_time: float = 0.0,
|
min_confidence: float = 0.3,
|
) -> Optional[Tuple[float, float]]:
|
if not time_scores:
|
return None
|
candidates = [(t, s) for t, s in time_scores if t >= min_time and s >= min_confidence]
|
if not candidates:
|
candidates = time_scores
|
best = max(candidates, key=lambda x: x[1])
|
if best[1] < 0.1:
|
return None
|
return best
|
|
|
def find_peaks_ordered(
|
sf_scores: List[Tuple[float, float]],
|
ho_scores: List[Tuple[float, float]],
|
duration: float,
|
min_gap: float = 30.0,
|
) -> Tuple[Optional[Tuple[float, float]], Optional[Tuple[float, float]]]:
|
sf = find_peak(smooth_scores(sf_scores))
|
min_ho = (sf[0] + min_gap) if sf else 0.0
|
ho = find_peak(smooth_scores(ho_scores), min_time=min_ho)
|
if sf and ho and ho[0] <= sf[0]:
|
ho = find_peak(smooth_scores(ho_scores), min_time=sf[0] + 1.0)
|
if sf and not ho and duration > sf[0] + min_gap:
|
ho = find_peak(smooth_scores(ho_scores), min_time=sf[0] + min_gap)
|
return sf, ho
|