feat: add Opus 32k/48k/64k studio quality tiers
Adds three new codec IDs (Opus32k=6, Opus48k=7, Opus64k=8) and corresponding STUDIO_32K, STUDIO_48K, STUDIO_64K quality profiles. All use 20ms frames with minimal FEC (10%) for maximum quality on good networks. Updated across: wire protocol (codec_id.rs), encoder/decoder (opus_enc/dec.rs), adaptive codec switch (call.rs), CLI (--profile studio-64k), desktop engine + UI slider (8 quality levels from Studio 64k green to Codec2 1.2k red). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,13 +96,16 @@
|
||||
<span class="setting-label">QUALITY</span>
|
||||
<span id="s-quality-label" class="quality-label">Auto</span>
|
||||
</div>
|
||||
<input id="s-quality" type="range" min="0" max="4" step="1" value="0" class="quality-slider" />
|
||||
<input id="s-quality" type="range" min="0" max="7" step="1" value="3" class="quality-slider" />
|
||||
<div class="quality-ticks">
|
||||
<span>64k</span>
|
||||
<span>48k</span>
|
||||
<span>32k</span>
|
||||
<span>Auto</span>
|
||||
<span>Opus 24k</span>
|
||||
<span>Opus 6k</span>
|
||||
<span>C2 3.2k</span>
|
||||
<span>C2 1.2k</span>
|
||||
<span>24k</span>
|
||||
<span>6k</span>
|
||||
<span>C2</span>
|
||||
<span>1.2k</span>
|
||||
</div>
|
||||
</div>
|
||||
<label class="checkbox">
|
||||
|
||||
@@ -28,6 +28,9 @@ fn resolve_quality(quality: &str) -> Option<QualityProfile> {
|
||||
frame_duration_ms: 20,
|
||||
frames_per_block: 5,
|
||||
}),
|
||||
"studio-32k" => Some(QualityProfile::STUDIO_32K),
|
||||
"studio-48k" => Some(QualityProfile::STUDIO_48K),
|
||||
"studio-64k" => Some(QualityProfile::STUDIO_64K),
|
||||
_ => None, // "auto" or unknown
|
||||
}
|
||||
}
|
||||
@@ -279,6 +282,9 @@ impl CallEngine {
|
||||
let new_profile = match pkt.header.codec_id {
|
||||
CodecId::Opus24k => QualityProfile::GOOD,
|
||||
CodecId::Opus6k => QualityProfile::DEGRADED,
|
||||
CodecId::Opus32k => QualityProfile::STUDIO_32K,
|
||||
CodecId::Opus48k => QualityProfile::STUDIO_48K,
|
||||
CodecId::Opus64k => QualityProfile::STUDIO_64K,
|
||||
CodecId::Codec2_1200 => QualityProfile::CATASTROPHIC,
|
||||
CodecId::Codec2_3200 => QualityProfile {
|
||||
codec: CodecId::Codec2_3200,
|
||||
|
||||
@@ -51,22 +51,20 @@ const sAgc = document.getElementById("s-agc") as HTMLInputElement;
|
||||
const sQuality = document.getElementById("s-quality") as HTMLInputElement;
|
||||
const sQualityLabel = document.getElementById("s-quality-label")!;
|
||||
|
||||
// Quality slider config
|
||||
const QUALITY_STEPS = ["auto", "good", "degraded", "codec2-3200", "catastrophic"];
|
||||
const QUALITY_LABELS = ["Auto", "Opus 24k", "Opus 6k", "Codec2 3.2k", "Codec2 1.2k"];
|
||||
const QUALITY_COLORS = ["#4ade80", "#4ade80", "#facc15", "#e97320", "#991b1b"];
|
||||
// Quality slider config — best (left/green) to worst (right/red)
|
||||
const QUALITY_STEPS = ["studio-64k", "studio-48k", "studio-32k", "auto", "good", "degraded", "codec2-3200", "catastrophic"];
|
||||
const QUALITY_LABELS = ["Studio 64k", "Studio 48k", "Studio 32k", "Auto", "Opus 24k", "Opus 6k", "Codec2 3.2k", "Codec2 1.2k"];
|
||||
const QUALITY_COLORS = ["#22c55e", "#4ade80", "#86efac", "#a3e635", "#facc15", "#f59e0b", "#e97320", "#991b1b"];
|
||||
|
||||
function qualityToIndex(q: string): number {
|
||||
const idx = QUALITY_STEPS.indexOf(q);
|
||||
return idx >= 0 ? idx : 0;
|
||||
return idx >= 0 ? idx : 3; // default to "auto" (index 3)
|
||||
}
|
||||
|
||||
function updateQualityUI(index: number) {
|
||||
sQualityLabel.textContent = QUALITY_LABELS[index];
|
||||
sQualityLabel.style.color = QUALITY_COLORS[index];
|
||||
const pct = index / (QUALITY_STEPS.length - 1);
|
||||
// Gradient: green at left → yellow middle → dark red at right
|
||||
sQuality.style.background = `linear-gradient(90deg, #4ade80 0%, #facc15 40%, #e97320 70%, #991b1b 100%)`;
|
||||
sQuality.style.background = `linear-gradient(90deg, #22c55e 0%, #86efac 25%, #facc15 50%, #e97320 75%, #991b1b 100%)`;
|
||||
}
|
||||
|
||||
sQuality.addEventListener("input", () => {
|
||||
|
||||
Reference in New Issue
Block a user