fix dashes

This commit is contained in:
Armin 2026-07-05 01:19:07 +02:00
commit c2ecb7eb46

View file

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tcd Audio Transcode Detector</title>
<title>tcd - Audio Transcode Detector</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
@ -44,11 +44,11 @@
<div class="metrics-grid" style="margin-top:10px">
<div class="metric-card">
<div class="metric-label">Live Peak</div>
<div class="metric-value" id="livePeak"></div>
<div class="metric-value" id="livePeak">-</div>
</div>
<div class="metric-card">
<div class="metric-label">Live Cutoff</div>
<div class="metric-value" id="liveCutoff"></div>
<div class="metric-value" id="liveCutoff">-</div>
</div>
</div>
</section>
@ -56,14 +56,14 @@
<section id="fileInfo">
<h2>File Information</h2>
<div class="info-grid">
<div class="info-item fullwidth"><span class="info-label">Filename</span><span id="fileName" class="info-value"></span></div>
<div class="info-item"><span class="info-label">Format</span><span id="fileFormat" class="info-value"></span></div>
<div class="info-item"><span class="info-label">Sample Rate</span><span id="fileSampleRate" class="info-value"></span></div>
<div class="info-item"><span class="info-label">Channels</span><span class="info-value"><span id="fileChannels"></span> <span id="fileStereoMode" class="info-value-tag"></span></span></div>
<div class="info-item"><span class="info-label">Duration</span><span id="fileDuration" class="info-value"></span></div>
<div class="info-item"><span class="info-label">Bitrate</span><span class="info-value"><span id="fileBitrate"></span> <span id="fileBitrateMode" class="info-value-tag"></span></span></div>
<div class="info-item"><span class="info-label">File Size</span><span id="fileSize" class="info-value"></span></div>
<div class="info-item"><span class="info-label">BPM</span><span class="info-value bpm-value"><span id="fileBPM"></span><span class="bpm-buttons"><button class="bpm-btn" id="bpmHalf" title="Halve">÷2</button><button class="bpm-btn" id="bpmDouble" title="Double">×2</button></span></span></div>
<div class="info-item fullwidth"><span class="info-label">Filename</span><span id="fileName" class="info-value">-</span></div>
<div class="info-item"><span class="info-label">Format</span><span id="fileFormat" class="info-value">-</span></div>
<div class="info-item"><span class="info-label">Sample Rate</span><span id="fileSampleRate" class="info-value">-</span></div>
<div class="info-item"><span class="info-label">Channels</span><span class="info-value"><span id="fileChannels">-</span> <span id="fileStereoMode" class="info-value-tag"></span></span></div>
<div class="info-item"><span class="info-label">Duration</span><span id="fileDuration" class="info-value">-</span></div>
<div class="info-item"><span class="info-label">Bitrate</span><span class="info-value"><span id="fileBitrate">-</span> <span id="fileBitrateMode" class="info-value-tag"></span></span></div>
<div class="info-item"><span class="info-label">File Size</span><span id="fileSize" class="info-value">-</span></div>
<div class="info-item"><span class="info-label">BPM</span><span class="info-value bpm-value"><span id="fileBPM">-</span><span class="bpm-buttons"><button class="bpm-btn" id="bpmHalf" title="Halve">÷2</button><button class="bpm-btn" id="bpmDouble" title="Double">×2</button></span></span></div>
</div>
</section>
@ -83,50 +83,50 @@
<section id="metricsSection">
<h2>Key Metrics</h2>
<div class="metrics-grid">
<div class="metric-card" title="Peak Magnitude highest spectral amplitude in dBFS (0 dBFS = full scale).&#10;&#10;How to read:&#10;• > -1 dBFS: Heavily limited/mastered, extremely loud&#10;• -6 to -1 dBFS: Typical modern mastering&#10;• -12 to -6 dBFS: Conservative, good headroom&#10;• < -12 dBFS: Quiet or attenuated&#10;&#10;Significance: Combined with noise floor, indicates the effective dynamic range of the audio.">
<div class="metric-card" title="Peak Magnitude - highest spectral amplitude in dBFS (0 dBFS = full scale).&#10;&#10;How to read:&#10;• > -1 dBFS: Heavily limited/mastered, extremely loud&#10;• -6 to -1 dBFS: Typical modern mastering&#10;• -12 to -6 dBFS: Conservative, good headroom&#10;• < -12 dBFS: Quiet or attenuated&#10;&#10;Significance: Combined with noise floor, indicates the effective dynamic range of the audio.">
<div class="metric-label">Peak</div>
<div class="metric-value" id="mPeak"></div>
<div class="metric-value" id="mPeak">-</div>
</div>
<div class="metric-card" title="Spectral Cutoff highest frequency bin with significant energy above floor, as Hz and % of Nyquist (sample rate / 2).&#10;&#10;How to read:&#10;• ≥ 20 kHz (≥ 90%): Full bandwidth lossless or high-bitrate lossy (320k MP3, 256k AAC)&#10;• 16-19 kHz (70-85%): ~192k MP3 / ~128k AAC&#10;• 14-16 kHz (60-70%): ~128k MP3&#10;• 10-14 kHz (45-60%): ~64-96k lossy&#10;• < 10 kHz (< 45%): Very low bitrate (< 64k)&#10;&#10;Significance: The single strongest indicator of lossy compression. Lower cutoff = more aggressive compression.">
<div class="metric-card" title="Spectral Cutoff - highest frequency bin with significant energy above floor, as Hz and % of Nyquist (sample rate / 2).&#10;&#10;How to read:&#10;• ≥ 20 kHz (≥ 90%): Full bandwidth - lossless or high-bitrate lossy (320k MP3, 256k AAC)&#10;• 16-19 kHz (70-85%): ~192k MP3 / ~128k AAC&#10;• 14-16 kHz (60-70%): ~128k MP3&#10;• 10-14 kHz (45-60%): ~64-96k lossy&#10;• < 10 kHz (< 45%): Very low bitrate (< 64k)&#10;&#10;Significance: The single strongest indicator of lossy compression. Lower cutoff = more aggressive compression.">
<div class="metric-label">Cutoff</div>
<div class="metric-value" id="mCutoff"></div>
<div class="metric-value" id="mCutoff">-</div>
</div>
<div class="metric-card" title="Transition Bandwidth (Steepness) frequency gap between the -20 dBFS and -60 dBFS points. Measures how abruptly high-frequencies drop off.&#10;&#10;How to read:&#10;• < 500 Hz: Brick-wall cutoff — transcode or low-bitrate lossy&#10;• 500-1500 Hz: Moderately sharp — suspicious, may be higher-bitrate lossy&#10;• 1500-3000 Hz: Gradual rolloff — typical of genuine lossless&#10;• > 3000 Hz: Very gradual — natural rolloff from analog sources&#10;&#10;Significance: The strongest differentiator between genuine lossless and transcodes. Lossy encoders produce artificially steep lowpass filters.">
<div class="metric-card" title="Transition Bandwidth (Steepness) - frequency gap between the -20 dBFS and -60 dBFS points. Measures how abruptly high-frequencies drop off.&#10;&#10;How to read:&#10;• < 500 Hz: Brick-wall cutoff - transcode or low-bitrate lossy&#10;• 500-1500 Hz: Moderately sharp - suspicious, may be higher-bitrate lossy&#10;• 1500-3000 Hz: Gradual rolloff - typical of genuine lossless&#10;• > 3000 Hz: Very gradual - natural rolloff from analog sources&#10;&#10;Significance: The strongest differentiator between genuine lossless and transcodes. Lossy encoders produce artificially steep lowpass filters.">
<div class="metric-label">Steepness</div>
<div class="metric-value" id="mSteepness"></div>
<div class="metric-value" id="mSteepness">-</div>
</div>
<div class="metric-card" title="Noise Floor average magnitude in the top quarter of the spectrum (> 3/4 Nyquist), in dB relative to peak.&#10;&#10;How to read:&#10;• < -90 dB: Excellent — extremely clean, high dynamic range&#10;• -80 to -90 dB: Very good — typical of quality lossless&#10;• -70 to -80 dB: Moderate — some quantization noise present&#10;• -60 to -70 dB: Elevated — suggests lossy compression or analog hiss&#10;• > -60 dB: High — almost certainly lossy compressed&#10;&#10;Significance: Lossy codecs raise the noise floor through quantization. High noise floor + sharp cutoff = strong transcode indicator.">
<div class="metric-card" title="Noise Floor - average magnitude in the top quarter of the spectrum (> 3/4 Nyquist), in dB relative to peak.&#10;&#10;How to read:&#10;• < -90 dB: Excellent - extremely clean, high dynamic range&#10;• -80 to -90 dB: Very good - typical of quality lossless&#10;• -70 to -80 dB: Moderate - some quantization noise present&#10;• -60 to -70 dB: Elevated - suggests lossy compression or analog hiss&#10;• > -60 dB: High - almost certainly lossy compressed&#10;&#10;Significance: Lossy codecs raise the noise floor through quantization. High noise floor + sharp cutoff = strong transcode indicator.">
<div class="metric-label">Noise Floor</div>
<div class="metric-value" id="mNoise"></div>
<div class="metric-value" id="mNoise">-</div>
</div>
<div class="metric-card" title="Spectral Roughness (CoV) coefficient of variation (σ/μ) of spectral magnitudes in the 60-95% region below cutoff. Measures how uneven/scalloped the spectrum is.&#10;&#10;How to read:&#10;• > 0.40: Strong spectral scalloping — clear lossy encoding signature&#10;• 0.30-0.40: Moderate scalloping — suspicious, may be high-bitrate lossy&#10;• 0.15-0.30: Mild unevenness — needs band-ratio correlation&#10;• < 0.15: Smooth spectrum — typical of genuine lossless&#10;&#10;Significance: Lossy codecs create a comb-filter pattern via frequency-bin quantization. High roughness = high probability of lossy encoding.">
<div class="metric-card" title="Spectral Roughness (CoV) - coefficient of variation (σ/μ) of spectral magnitudes in the 60-95% region below cutoff. Measures how uneven/scalloped the spectrum is.&#10;&#10;How to read:&#10;• > 0.40: Strong spectral scalloping - clear lossy encoding signature&#10;• 0.30-0.40: Moderate scalloping - suspicious, may be high-bitrate lossy&#10;• 0.15-0.30: Mild unevenness - needs band-ratio correlation&#10;• < 0.15: Smooth spectrum - typical of genuine lossless&#10;&#10;Significance: Lossy codecs create a comb-filter pattern via frequency-bin quantization. High roughness = high probability of lossy encoding.">
<div class="metric-label">Roughness</div>
<div class="metric-value" id="mRoughness"></div>
<div class="metric-value" id="mRoughness">-</div>
</div>
<div class="metric-card" title="Band Ratio ratio of average spectral energy in 16-20 kHz band to 12-16 kHz band. Detects unnatural high-frequency tilt.&#10;&#10;How to read:&#10;• < 0.5: Normal natural rolloff in top octave&#10;• 0.5-0.9: Typical for most recordings&#10;• 0.9-1.0: Flat HF possible spectral reshaping from lossy encoding&#10;• > 1.0: Inverted tilt (more energy at 16-20 kHz than below) strong transcode signature&#10;&#10;Significance: Used as secondary criterion when cutoff is high but roughness is ambiguous. Transcodes often show unnatural energy distribution in the top octaves.">
<div class="metric-card" title="Band Ratio - ratio of average spectral energy in 16-20 kHz band to 12-16 kHz band. Detects unnatural high-frequency tilt.&#10;&#10;How to read:&#10;• < 0.5: Normal natural rolloff in top octave&#10;• 0.5-0.9: Typical for most recordings&#10;• 0.9-1.0: Flat HF - possible spectral reshaping from lossy encoding&#10;• > 1.0: Inverted tilt (more energy at 16-20 kHz than below) - strong transcode signature&#10;&#10;Significance: Used as secondary criterion when cutoff is high but roughness is ambiguous. Transcodes often show unnatural energy distribution in the top octaves.">
<div class="metric-label">Band Ratio</div>
<div class="metric-value" id="mBandRatio"></div>
<div class="metric-value" id="mBandRatio">-</div>
</div>
</div>
<div class="analysis-info">
<span><strong>Windows:</strong> <span id="windowsCount"></span></span>
<span><strong>FFT:</strong> <span id="fftSize"></span></span>
<span><strong>Windows:</strong> <span id="windowsCount">-</span></span>
<span><strong>FFT:</strong> <span id="fftSize">-</span></span>
</div>
</section>
<section id="decisionSection" title="Verdict the overall classification of the audio file based on spectral analysis.&#10;&#10;NATIVE: File matches its declared lossy format at a consistent bitrate (single encode).&#10;UPSCALED: Lossy file re-encoded to a higher bitrate than the original source.&#10;GENUINE: File appears to be native lossless (no transcode artifacts detected).&#10;TRANSCODE: Lossy source re-encoded to a lossless format (e.g. 128k MP3 → FLAC).&#10;&#10;The verdict is decided by: cutoff ratio, transition bandwidth (steepness), roughness (CoV), and band-ratio analysis against adaptive thresholds.">
<section id="decisionSection" title="Verdict - the overall classification of the audio file based on spectral analysis.&#10;&#10;NATIVE: File matches its declared lossy format at a consistent bitrate (single encode).&#10;UPSCALED: Lossy file re-encoded to a higher bitrate than the original source.&#10;GENUINE: File appears to be native lossless (no transcode artifacts detected).&#10;TRANSCODE: Lossy source re-encoded to a lossless format (e.g. 128k MP3 → FLAC).&#10;&#10;The verdict is decided by: cutoff ratio, transition bandwidth (steepness), roughness (CoV), and band-ratio analysis against adaptive thresholds.">
<h2>Decision</h2>
<div id="decision" class="decision-text"></div>
<div class="confidence-container" title="Validity Confidence how strongly the evidence supports the verdict, from 0% (random chance) to 100% (certain).&#10;&#10;85-100%: Very strong evidence — multiple criteria agree decisively.&#10;70-84%: Strong evidence — most criteria support the verdict.&#10;50-69%: Moderate evidence — some criteria triggered but not all.&#10;30-49%: Weak evidence — marginal, borderline detection.&#10;0-29%: Inconclusive — possible false positive, or audio is ambiguous.&#10;&#10;For lossy files: confidence is based on how far below the expected cutoff ratio the file sits.&#10;For lossless candidates: confidence blends cutoff ratio margin, steepness margin, and (above 80% Nyquist) secondary roughness + band-ratio criteria.">
<div id="decision" class="decision-text">-</div>
<div class="confidence-container" title="Validity Confidence - how strongly the evidence supports the verdict, from 0% (random chance) to 100% (certain).&#10;&#10;85-100%: Very strong evidence - multiple criteria agree decisively.&#10;70-84%: Strong evidence - most criteria support the verdict.&#10;50-69%: Moderate evidence - some criteria triggered but not all.&#10;30-49%: Weak evidence - marginal, borderline detection.&#10;0-29%: Inconclusive - possible false positive, or audio is ambiguous.&#10;&#10;For lossy files: confidence is based on how far below the expected cutoff ratio the file sits.&#10;For lossless candidates: confidence blends cutoff ratio margin, steepness margin, and (above 80% Nyquist) secondary roughness + band-ratio criteria.">
<div class="confidence-label">Validity Confidence</div>
<div class="confidence-bar-bg">
<div id="confidenceBar" class="confidence-bar-fill" style="width:0%">0%</div>
</div>
<div id="confidenceLabel" class="confidence-label-small"></div>
<div id="confidenceLabel" class="confidence-label-small">-</div>
</div>
</section>
<section id="factors" title="Factor Analysis step-by-step breakdown of the detection criteria used to reach the verdict.&#10;&#10;① PRIMARY criteria (applied to ALL files):&#10; Compares transition bandwidth (steepness) to an adaptive threshold based on cutoff ratio.&#10; If steepness is BELOW the threshold, the spectrum has an artificially sharp cutoff → transcode flagged.&#10; Files with cutoff_ratio ≥ 0.99 (full spectrum) bypass this check.&#10;&#10;② SECONDARY criteria (applied when cutoff_ratio > 0.80):&#10; Checks spectral roughness (CoV) and band ratio for additional transcode signatures.&#10; High roughness (> 0.40) alone is sufficient to confirm. Moderate roughness needs band-ratio corroboration.&#10;&#10;Lossy files: checked only for cutoff ratio vs expected range for the bitrate.&#10;✓ = criterion met (supports transcode/upscaled), ✗ = criterion not met (supports genuine/native).">
<section id="factors" title="Factor Analysis - step-by-step breakdown of the detection criteria used to reach the verdict.&#10;&#10;① PRIMARY criteria (applied to ALL files):&#10; Compares transition bandwidth (steepness) to an adaptive threshold based on cutoff ratio.&#10; If steepness is BELOW the threshold, the spectrum has an artificially sharp cutoff → transcode flagged.&#10; Files with cutoff_ratio ≥ 0.99 (full spectrum) bypass this check.&#10;&#10;② SECONDARY criteria (applied when cutoff_ratio > 0.80):&#10; Checks spectral roughness (CoV) and band ratio for additional transcode signatures.&#10; High roughness (> 0.40) alone is sufficient to confirm. Moderate roughness needs band-ratio corroboration.&#10;&#10;Lossy files: checked only for cutoff ratio vs expected range for the bitrate.&#10;✓ = criterion met (supports transcode/upscaled), ✗ = criterion not met (supports genuine/native).">
<section id="dataSection">
<h2>Analysis Data</h2>
@ -143,7 +143,7 @@
</div>
<footer>
<p>Based on <a href="https://codeberg.org/armin/tcd" target="_blank">tcd</a> Psychoacoustic audio authenticity analysis</p>
<p>Based on <a href="https://codeberg.org/armin/tcd" target="_blank">tcd</a> - Psychoacoustic audio authenticity analysis</p>
</footer>
</div>