doum
2 天以前 ce44d803b73a65b2cc31db5bcc662139029463d3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# -*- 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