Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions internal/processor/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2724,6 +2724,11 @@ const (
crosstalkKurtosisThreshold = 10.0 // Above this + voice centroid = likely crosstalk
crosstalkCrestFactorThreshold = 15.0 // Above this + voice centroid = likely crosstalk
crosstalkPeakRMSGap = 45.0 // dB - catches severe transient contamination regardless of spectral content
// silenceCrestFactorMax is the maximum acceptable crest factor for silence candidates.
// Crest factor > 25 dB indicates physical transients (bumps, interference) contaminating
// the silence region, making noise floor measurements unreliable.
// Normal room tone: 5-20 dB; contaminated: 25-45 dB.
silenceCrestFactorMax = 25.0 // dB - hard rejection above this

// Crest factor penalty thresholds for silence candidates.
// Context: These apply to SILENCE CANDIDATES (RMS < -70 dBFS).
Expand Down Expand Up @@ -2902,6 +2907,19 @@ func scoreSilenceCandidate(m *SilenceCandidateMetrics) float64 {
return 0.0 // Reject this candidate
}

// Hard rejection: extreme crest factor indicates physical transients (bumps,
// interference) contaminating the silence region. Unlike the crosstalk check
// (45 dB), this catches moderate contamination (25-45 dB range).
if m.CrestFactor > silenceCrestFactorMax {
debugLog("scoreSilenceCandidate: REJECTING candidate at %.3fs - crest factor %.1f dB exceeds %.1f dB threshold",
m.Region.Start.Seconds(), m.CrestFactor, silenceCrestFactorMax)
m.TransientWarning = fmt.Sprintf(
"rejected: crest factor %.1f dB exceeds %.1f dB threshold (transient contamination)",
m.CrestFactor, silenceCrestFactorMax,
)
return 0.0
}

// Calculate individual component scores (all normalised to 0-1 range)
ampScore := calculateAmplitudeScore(m.RMSLevel)
specScore := calculateSpectralScore(m.SpectralCentroid, m.SpectralFlatness, m.SpectralKurtosis)
Expand Down
2 changes: 1 addition & 1 deletion testdata/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ analysis: mark-analysis martin-analysis popey-analysis
# Process all presenters for episodes 70, 71, and 72
all-episodes:
#!/usr/bin/env bash
for ep in 68 69 70 71 72 73 74; do
for ep in 68 69 70 71 72 73 74 75; do
echo "=== Processing Episode $ep ==="
for presenter in mark martin popey; do
echo "--- $presenter ---"
Expand Down