Level 3: small fixes and report
This commit is contained in:
@@ -111,21 +111,6 @@ def _thresholds_from_smr(
|
||||
|
||||
return T
|
||||
|
||||
def _normalize_global_gain(G: GlobalGain) -> float | FloatArray:
|
||||
"""
|
||||
Normalize GlobalGain to match AACChannelFrameF3["G"] type:
|
||||
- long: return float
|
||||
- ESH: return float64 ndarray of shape (1, 8)
|
||||
"""
|
||||
if np.isscalar(G):
|
||||
return float(G)
|
||||
|
||||
G_arr = np.asarray(G)
|
||||
if G_arr.size == 1:
|
||||
return float(G_arr.reshape(-1)[0])
|
||||
|
||||
return np.asarray(G_arr, dtype=np.float64)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Public helpers (useful for level_x demo wrappers)
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -476,10 +461,6 @@ def aac_coder_3(
|
||||
S_L, sfc_L, G_L = aac_quantizer(chl_f_tns, frame_type, SMR_L)
|
||||
S_R, sfc_R, G_R = aac_quantizer(chr_f_tns, frame_type, SMR_R)
|
||||
|
||||
# Normalize G types for AACSeq3 schema (float | float64 ndarray).
|
||||
G_Ln = _normalize_global_gain(G_L)
|
||||
G_Rn = _normalize_global_gain(G_R)
|
||||
|
||||
# Huffman-code ONLY the DPCM differences for b>0.
|
||||
# sfc[0] corresponds to alpha(0)=G and is stored separately in the frame.
|
||||
sfc_L_dpcm = np.asarray(sfc_L, dtype=np.int64)[1:, ...]
|
||||
@@ -503,7 +484,7 @@ def aac_coder_3(
|
||||
"chl": {
|
||||
"tns_coeffs": np.asarray(chl_tns_coeffs, dtype=np.float64),
|
||||
"T": np.asarray(T_L, dtype=np.float64),
|
||||
"G": G_Ln,
|
||||
"G": G_L,
|
||||
"sfc": sfc_L_stream,
|
||||
"stream": mdct_L_stream,
|
||||
"codebook": int(cb_L),
|
||||
@@ -511,7 +492,7 @@ def aac_coder_3(
|
||||
"chr": {
|
||||
"tns_coeffs": np.asarray(chr_tns_coeffs, dtype=np.float64),
|
||||
"T": np.asarray(T_R, dtype=np.float64),
|
||||
"G": G_Rn,
|
||||
"G": G_R,
|
||||
"sfc": sfc_R_stream,
|
||||
"stream": mdct_R_stream,
|
||||
"codebook": int(cb_R),
|
||||
|
||||
@@ -42,7 +42,7 @@ def _nbands(frame_type: FrameType) -> int:
|
||||
# Public helpers
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def aac_unpack_seq_channels_to_frame_f(frame_type: FrameType, chl_f: FrameChannelF, chr_f: FrameChannelF) -> FrameF:
|
||||
def aac_unpack_seq_channels(frame_type: FrameType, chl_f: FrameChannelF, chr_f: FrameChannelF) -> FrameF:
|
||||
"""
|
||||
Re-pack per-channel spectra from the Level-1 AACSeq1 schema into the stereo
|
||||
FrameF container expected by aac_i_filter_bank().
|
||||
@@ -167,7 +167,7 @@ def aac_decoder_1(
|
||||
chl_f = np.asarray(fr["chl"]["frame_F"], dtype=np.float64)
|
||||
chr_f = np.asarray(fr["chr"]["frame_F"], dtype=np.float64)
|
||||
|
||||
frame_f: FrameF = aac_unpack_seq_channels_to_frame_f(frame_type, chl_f, chr_f)
|
||||
frame_f: FrameF = aac_unpack_seq_channels(frame_type, chl_f, chr_f)
|
||||
frame_t_hat: FrameT = aac_i_filter_bank(frame_f, frame_type, win_type) # (2048, 2)
|
||||
|
||||
start = i * hop
|
||||
@@ -427,7 +427,7 @@ def aac_decoder_3(
|
||||
X_R = aac_i_tns(Xq_R, frame_type, tns_R)
|
||||
|
||||
# Re-pack to stereo container and inverse filterbank
|
||||
frame_f = aac_unpack_seq_channels_to_frame_f(frame_type, np.asarray(X_L), np.asarray(X_R))
|
||||
frame_f = aac_unpack_seq_channels(frame_type, np.asarray(X_L), np.asarray(X_R))
|
||||
frame_t_hat: FrameT = aac_i_filter_bank(frame_f, frame_type, win_type)
|
||||
|
||||
start = i * hop
|
||||
|
||||
@@ -189,7 +189,7 @@ def _predictability(
|
||||
# Band-domain aggregation
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def _band_energy_and_weighted_predictability(
|
||||
def _band_energy_and_pred(
|
||||
r: FloatArray,
|
||||
c: FloatArray,
|
||||
wlow: BandIndexArray,
|
||||
@@ -238,7 +238,7 @@ def _band_energy_and_weighted_predictability(
|
||||
return e_b, c_num_b
|
||||
|
||||
|
||||
def _psycho_one_window(
|
||||
def _psycho_window(
|
||||
time_x: FrameChannelT,
|
||||
prev1_x: FrameChannelT,
|
||||
prev2_x: FrameChannelT,
|
||||
@@ -288,7 +288,7 @@ def _psycho_one_window(
|
||||
c_w = _predictability(r, phi, r_m1, phi_m1, r_m2, phi_m2)
|
||||
|
||||
# Aggregate into psycho bands
|
||||
e_b, c_num_b = _band_energy_and_weighted_predictability(r, c_w, wlow, whigh)
|
||||
e_b, c_num_b = _band_energy_and_pred(r, c_w, wlow, whigh)
|
||||
|
||||
# Spread energies and predictability across bands:
|
||||
# ecb(b) = sum_bb e(bb) * S(bb, b)
|
||||
@@ -333,7 +333,7 @@ def _psycho_one_window(
|
||||
# ESH window slicing (match filterbank conventions)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def _esh_subframes_256(x_2048: FrameChannelT) -> list[FrameChannelT]:
|
||||
def _esh_subframes(x_2048: FrameChannelT) -> list[FrameChannelT]:
|
||||
"""
|
||||
Extract the 8 overlapping 256-sample short windows used by AAC ESH.
|
||||
|
||||
@@ -408,7 +408,7 @@ def aac_psycho(
|
||||
|
||||
# Long frame types: compute one SMR vector (69 bands)
|
||||
if frame_type != "ESH":
|
||||
return _psycho_one_window(frame_T, frame_T_prev_1, frame_T_prev_2, N=N, table=table)
|
||||
return _psycho_window(frame_T, frame_T_prev_1, frame_T_prev_2, N=N, table=table)
|
||||
|
||||
# ESH: compute 8 SMR vectors (42 bands each), one per short subframe.
|
||||
#
|
||||
@@ -419,8 +419,8 @@ def aac_psycho(
|
||||
#
|
||||
# This matches the "within-frame history" convention commonly used in
|
||||
# simplified psycho models for ESH.
|
||||
cur_subs = _esh_subframes_256(frame_T)
|
||||
prev1_subs = _esh_subframes_256(frame_T_prev_1)
|
||||
cur_subs = _esh_subframes(frame_T)
|
||||
prev1_subs = _esh_subframes(frame_T_prev_1)
|
||||
|
||||
B = int(table.shape[0]) # expected 42
|
||||
smr_out = np.zeros((B, 8), dtype=np.float64)
|
||||
@@ -436,6 +436,6 @@ def aac_psycho(
|
||||
x_m1 = cur_subs[j - 1]
|
||||
x_m2 = cur_subs[j - 2]
|
||||
|
||||
smr_out[:, j] = _psycho_one_window(cur_subs[j], x_m1, x_m2, N=256, table=table)
|
||||
smr_out[:, j] = _psycho_window(cur_subs[j], x_m1, x_m2, N=256, table=table)
|
||||
|
||||
return smr_out
|
||||
|
||||
@@ -35,7 +35,7 @@ MAX_SF_DELTA:int = 60
|
||||
# -----------------------------------------------------------------------------
|
||||
# Helpers: ESH packing/unpacking (128x8 <-> 1024x1)
|
||||
# -----------------------------------------------------------------------------
|
||||
def _esh_pack_to_1024(x_128x8: FloatArray) -> FloatArray:
|
||||
def _esh_pack(x_128x8: FloatArray) -> FloatArray:
|
||||
"""
|
||||
Pack ESH coefficients (128 x 8) into a single long vector (1024 x 1).
|
||||
|
||||
@@ -58,7 +58,7 @@ def _esh_pack_to_1024(x_128x8: FloatArray) -> FloatArray:
|
||||
return x_128x8.reshape(1024, 1, order="F")
|
||||
|
||||
|
||||
def _esh_unpack_from_1024(x_1024x1: FloatArray) -> FloatArray:
|
||||
def _esh_unpack(x_1024x1: FloatArray) -> FloatArray:
|
||||
"""
|
||||
Unpack a packed ESH vector (1024 elements) back to shape (128, 8).
|
||||
|
||||
@@ -226,7 +226,7 @@ def _band_energy(x: FloatArray, lo: int, hi: int) -> float:
|
||||
return float(np.sum(sec * sec))
|
||||
|
||||
|
||||
def _threshold_T_from_SMR(
|
||||
def _psychoacoustic_threshold(
|
||||
X: FloatArray,
|
||||
SMR_col: FloatArray,
|
||||
bands: list[tuple[int, int]],
|
||||
@@ -425,7 +425,7 @@ def aac_quantizer(
|
||||
SMRj = SMR[:, j].reshape(NB)
|
||||
|
||||
# Compute psychoacoustic threshold T(b) for this subframe
|
||||
T = _threshold_T_from_SMR(Xj, SMRj, bands)
|
||||
T = _psychoacoustic_threshold(Xj, SMRj, bands)
|
||||
|
||||
# Frame-wise initial estimate alpha_hat (Equation 14)
|
||||
alpha_hat = _initial_alpha_hat(Xj)
|
||||
@@ -482,7 +482,7 @@ def aac_quantizer(
|
||||
raise ValueError(f"For non-ESH, SMR must have shape ({NB},) or ({NB}, 1).")
|
||||
|
||||
# Compute psychoacoustic threshold T(b) for the long frame
|
||||
T = _threshold_T_from_SMR(Xv, SMRv, bands)
|
||||
T = _psychoacoustic_threshold(Xv, SMRv, bands)
|
||||
|
||||
# Frame-wise initial estimate alpha_hat (Equation 14)
|
||||
alpha_hat = _initial_alpha_hat(Xv)
|
||||
@@ -566,7 +566,7 @@ def aac_i_quantizer(
|
||||
if sfc.shape != (NB, 8):
|
||||
raise ValueError(f"For ESH, sfc must have shape ({NB}, 8).")
|
||||
|
||||
S_128x8 = _esh_unpack_from_1024(S_flat)
|
||||
S_128x8 = _esh_unpack(S_flat)
|
||||
|
||||
Xrec = np.zeros((128, 8), dtype=np.float64)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ from core.aac_types import *
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _band_ranges_for_kcount(k_count: int) -> BandRanges:
|
||||
def _band_ranges(k_count: int) -> BandRanges:
|
||||
"""
|
||||
Return Bark band index ranges [start, end] (inclusive) for the given MDCT line count.
|
||||
|
||||
@@ -66,7 +66,7 @@ def _band_ranges_for_kcount(k_count: int) -> BandRanges:
|
||||
start = tbl[:, 1].astype(int)
|
||||
end = tbl[:, 2].astype(int)
|
||||
|
||||
ranges: list[tuple[int, int]] = [(int(s), int(e)) for s, e in zip(start, end)]
|
||||
ranges: BandRanges = [(int(s), int(e)) for s, e in zip(start, end)]
|
||||
|
||||
for s, e in ranges:
|
||||
if s < 0 or e < s or e >= k_count:
|
||||
@@ -117,7 +117,7 @@ def _compute_sw(x: MdctCoeffs) -> MdctCoeffs:
|
||||
x = np.asarray(x, dtype=np.float64).reshape(-1)
|
||||
k_count = int(x.shape[0])
|
||||
|
||||
bands = _band_ranges_for_kcount(k_count)
|
||||
bands = _band_ranges(k_count)
|
||||
sw = np.zeros(k_count, dtype=np.float64)
|
||||
|
||||
for s, e in bands:
|
||||
@@ -347,7 +347,7 @@ def _apply_itns_iir(y: MdctCoeffs, a_q: MdctCoeffs) -> MdctCoeffs:
|
||||
return x_hat
|
||||
|
||||
|
||||
def _tns_one_vector(x: MdctCoeffs) -> tuple[MdctCoeffs, MdctCoeffs]:
|
||||
def _tns_vector(x: MdctCoeffs) -> tuple[MdctCoeffs, MdctCoeffs]:
|
||||
"""
|
||||
TNS for a single MDCT vector (one long frame or one short subframe).
|
||||
|
||||
@@ -430,7 +430,7 @@ def aac_tns(frame_F_in: FrameChannelF, frame_type: FrameType) -> Tuple[FrameChan
|
||||
a_out = np.empty((PRED_ORDER, 8), dtype=np.float64)
|
||||
|
||||
for j in range(8):
|
||||
y[:, j], a_out[:, j] = _tns_one_vector(x[:, j])
|
||||
y[:, j], a_out[:, j] = _tns_vector(x[:, j])
|
||||
|
||||
return y, a_out
|
||||
|
||||
@@ -443,7 +443,7 @@ def aac_tns(frame_F_in: FrameChannelF, frame_type: FrameType) -> Tuple[FrameChan
|
||||
else:
|
||||
raise ValueError('For non-ESH, frame_F_in must have shape (1024,) or (1024, 1).')
|
||||
|
||||
y_vec, a_q = _tns_one_vector(x_vec)
|
||||
y_vec, a_q = _tns_vector(x_vec)
|
||||
|
||||
if out_shape == (1024,):
|
||||
y_out = y_vec
|
||||
|
||||
@@ -163,6 +163,42 @@ def snr_db(x_ref: StereoSignal, x_hat: StereoSignal) -> float:
|
||||
return float(10.0 * np.log10(ps / pn))
|
||||
|
||||
|
||||
def estimate_lag_mono(x_ref: TimeSignal, x_hat: TimeSignal, max_lag=4096):
|
||||
"""
|
||||
Estimate time lag between two mono signals.
|
||||
Returns lag (positive means x_hat delayed).
|
||||
"""
|
||||
n = min(len(x_ref), len(x_hat))
|
||||
x_ref = x_ref[:n]
|
||||
x_hat = x_hat[:n]
|
||||
|
||||
corr = np.correlate(x_ref, x_hat, mode='full')
|
||||
lags = np.arange(-n + 1, n)
|
||||
|
||||
center = n - 1
|
||||
lo = max(0, center - max_lag)
|
||||
hi = min(len(corr), center + max_lag + 1)
|
||||
|
||||
best = lo + int(np.argmax(corr[lo:hi]))
|
||||
return int(lags[best])
|
||||
|
||||
|
||||
def match_gain(x_ref: StereoSignal, x_hat: StereoSignal) -> float:
|
||||
"""
|
||||
Least-squares gain g that best maps x_hat -> x_ref.
|
||||
"""
|
||||
n = min(x_ref.shape[0], x_hat.shape[0])
|
||||
c = min(x_ref.shape[1], x_hat.shape[1])
|
||||
|
||||
r = x_ref[:n, :c].reshape(-1).astype(np.float64)
|
||||
h = x_hat[:n, :c].reshape(-1).astype(np.float64)
|
||||
|
||||
denom = float(np.dot(h, h))
|
||||
if denom <= 0.0:
|
||||
return 1.0
|
||||
return float(np.dot(r, h) / denom)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Psychoacoustic band tables (TableB219.mat)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -21,7 +21,7 @@ import soundfile as sf
|
||||
|
||||
from core.aac_coder import aac_coder_1, aac_coder_2, aac_coder_3, aac_read_wav_stereo_48k
|
||||
from core.aac_decoder import aac_decoder_1, aac_decoder_2, aac_decoder_3, aac_remove_padding
|
||||
from core.aac_utils import snr_db
|
||||
from core.aac_utils import snr_db, estimate_lag_mono, match_gain
|
||||
from core.aac_types import *
|
||||
|
||||
|
||||
@@ -151,6 +151,29 @@ def test_aac_coder_seq_schema_and_shapes(mk_random_stereo_wav: Path) -> None:
|
||||
assert chl_f.shape == (1024, 1)
|
||||
assert chr_f.shape == (1024, 1)
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_level_1_gain_close_to_one(
|
||||
mk_actual_stereo_wav: Path,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
Guardrail: decoded signal should not have a large global gain mismatch.
|
||||
"""
|
||||
x_ref, fs = aac_read_wav_stereo_48k(mk_actual_stereo_wav)
|
||||
assert int(fs) == 48000
|
||||
|
||||
out_wav = tmp_path / "decoded_level3.wav"
|
||||
aac_seq_1: AACSeq1 = aac_coder_1(mk_actual_stereo_wav)
|
||||
y_hat: StereoSignal = aac_decoder_1(aac_seq_1, out_wav)
|
||||
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
x_ref = x_ref[:n, :]
|
||||
y_hat = y_hat[:n, :]
|
||||
|
||||
g = match_gain(x_ref, y_hat)
|
||||
# print (f"g = {g}")
|
||||
# Allow some slack but catch big scaling regressions
|
||||
assert 0.75 <= g <= 1.25
|
||||
|
||||
@pytest.mark.parametrize("mk_random_stereo_wav", [0.5], indirect=True)
|
||||
def test_end_to_end_aac_coder_decoder_high_snr(mk_random_stereo_wav: Path, tmp_path: Path) -> None:
|
||||
@@ -207,6 +230,30 @@ def test_aac_coder_2_seq_schema_and_shapes(mk_random_stereo_wav: Path) -> None:
|
||||
assert coeffs.shape == (4, 1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_level_2_gain_close_to_one(
|
||||
mk_actual_stereo_wav: Path,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
Guardrail: decoded signal should not have a large global gain mismatch.
|
||||
"""
|
||||
x_ref, fs = aac_read_wav_stereo_48k(mk_actual_stereo_wav)
|
||||
assert int(fs) == 48000
|
||||
|
||||
out_wav = tmp_path / "decoded_level3.wav"
|
||||
aac_seq_2: AACSeq2 = aac_coder_2(mk_actual_stereo_wav)
|
||||
y_hat: StereoSignal = aac_decoder_2(aac_seq_2, out_wav)
|
||||
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
x_ref = x_ref[:n, :]
|
||||
y_hat = y_hat[:n, :]
|
||||
|
||||
g = match_gain(x_ref, y_hat)
|
||||
# print (f"g = {g}")
|
||||
# Allow some slack but catch big scaling regressions
|
||||
assert 0.75 <= g <= 1.25
|
||||
|
||||
@pytest.mark.parametrize("mk_random_stereo_wav", [0.5], indirect=True)
|
||||
def test_end_to_end_level_2_high_snr(mk_random_stereo_wav: Path, tmp_path: Path) -> None:
|
||||
x_ref, fs = sf.read(str(mk_random_stereo_wav), always_2d=True)
|
||||
@@ -294,6 +341,90 @@ def test_aac_coder_3_seq_schema_and_shapes(mk_actual_stereo_wav: Path) -> None:
|
||||
else:
|
||||
assert np.isscalar(G)
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_level_3_estimated_lag(
|
||||
mk_actual_stereo_wav: Path,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
Check that the estimated lag between reference and decoded
|
||||
signal is small (zero), to prevent catastrophic misalignment.
|
||||
"""
|
||||
x_ref, fs = aac_read_wav_stereo_48k(mk_actual_stereo_wav)
|
||||
assert int(fs) == 48000
|
||||
|
||||
out_wav = tmp_path / "decoded_level3.wav"
|
||||
|
||||
aac_seq_3: AACSeq3 = aac_coder_3(mk_actual_stereo_wav)
|
||||
y_hat: StereoSignal = aac_decoder_3(aac_seq_3, out_wav)
|
||||
|
||||
# Use only common length
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
x_ref = x_ref[:n, :]
|
||||
y_hat = y_hat[:n, :]
|
||||
|
||||
lag_L = estimate_lag_mono(x_ref[:, 0], y_hat[:, 0], max_lag=4096)
|
||||
lag_R = estimate_lag_mono(x_ref[:, 1], y_hat[:, 1], max_lag=4096)
|
||||
|
||||
# We allow zero latency
|
||||
assert abs(lag_L) == 0
|
||||
assert abs(lag_R) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_level_3_not_lr_swapped(
|
||||
mk_actual_stereo_wav: Path,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
Ensure the decoded stereo channels are not swapped.
|
||||
If channels are swapped, SNR against the original drops a lot,
|
||||
while SNR against swapped reference increases.
|
||||
"""
|
||||
x_ref, fs = aac_read_wav_stereo_48k(mk_actual_stereo_wav)
|
||||
assert int(fs) == 48000
|
||||
|
||||
out_wav = tmp_path / "decoded_level3.wav"
|
||||
|
||||
aac_seq_3: AACSeq3 = aac_coder_3(mk_actual_stereo_wav)
|
||||
y_hat: StereoSignal = aac_decoder_3(aac_seq_3, out_wav)
|
||||
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
x_ref = x_ref[:n, :]
|
||||
y_hat = y_hat[:n, :]
|
||||
|
||||
snr_normal = snr_db(x_ref, y_hat)
|
||||
snr_swapped = snr_db(x_ref[:, [1, 0]], y_hat)
|
||||
|
||||
# If the decoded output were swapped, snr_swapped would be significantly higher.
|
||||
assert snr_normal >= snr_swapped
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_level_3_gain_close_to_one(
|
||||
mk_actual_stereo_wav: Path,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""
|
||||
Guardrail: decoded signal should not have a large global gain mismatch.
|
||||
"""
|
||||
x_ref, fs = aac_read_wav_stereo_48k(mk_actual_stereo_wav)
|
||||
assert int(fs) == 48000
|
||||
|
||||
out_wav = tmp_path / "decoded_level3.wav"
|
||||
aac_seq_3: AACSeq3 = aac_coder_3(mk_actual_stereo_wav)
|
||||
y_hat: StereoSignal = aac_decoder_3(aac_seq_3, out_wav)
|
||||
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
x_ref = x_ref[:n, :]
|
||||
y_hat = y_hat[:n, :]
|
||||
|
||||
g = match_gain(x_ref, y_hat)
|
||||
|
||||
# Allow some slack but catch big scaling regressions
|
||||
assert 0.75 <= g <= 1.25
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mk_actual_stereo_wav", [0.5], indirect=True)
|
||||
def test_end_to_end_level_3_high_snr(mk_actual_stereo_wav: Path, tmp_path: Path) -> None:
|
||||
@@ -310,5 +441,4 @@ def test_end_to_end_level_3_high_snr(mk_actual_stereo_wav: Path, tmp_path: Path)
|
||||
|
||||
n = min(x_ref.shape[0], y_hat.shape[0])
|
||||
s = snr_db(x_ref[:n, :], y_hat[:n, :])
|
||||
# print(f" with SNR={s}")
|
||||
assert s > 7.0
|
||||
assert s > 8.0
|
||||
|
||||
Reference in New Issue
Block a user