/ challenges-old / string
Sign in
challenges-old / string
string / tools / challenge_tools / metrics.py
36 lines · 1.3 KBCodeBlameHistory
ddfc839Add string-pluck-v1 challenge, solution schema, and scoring toolsJeremy Magland 1"""Error measures between a solution and a reference, as defined in each challenge README."""
2from __future__ import annotations
4import numpy as np
7def waveform_l2(a: np.ndarray, r: np.ndarray) -> float:
8 return float(np.linalg.norm(a - r) / np.linalg.norm(r))
11def spectrogram(x: np.ndarray, n_fft: int, hop: int) -> np.ndarray:
12 """Magnitude STFT with a periodic Hann window, no padding. Shape (frames, n_fft//2 + 1)."""
13 j = np.arange(n_fft)
14 g = 0.5 * (1.0 - np.cos(2.0 * np.pi * j / n_fft))
15 m = (len(x) - n_fft) // hop + 1
16 idx = j[None, :] + hop * np.arange(m)[:, None]
17 frames = x[idx] * g[None, :]
18 return np.abs(np.fft.rfft(frames, axis=1))
21def spectrogram_l2(a: np.ndarray, r: np.ndarray, n_fft: int, hop: int) -> float:
22 sa = spectrogram(a, n_fft, hop)
23 sr = spectrogram(r, n_fft, hop)
24 return float(np.linalg.norm(sa - sr) / np.linalg.norm(sr))
27def compute_metric(name: str, a: np.ndarray, r: np.ndarray, params: dict) -> float:
28 if name == "waveform_l2":
29 return waveform_l2(a, r)
30 if name == "spectrogram_l2":
31 return spectrogram_l2(a, r, int(params["n_fft"]), int(params["hop"]))
32 raise KeyError(f"unknown metric {name}")
35def metric_names(challenge: dict) -> list[str]:
36 return [k for k in challenge["metrics"] if k != "primary"]
↑↓ move↵openescclose