fix: real VU meter levels from pipeline instead of random animation
- Added input_level and output_level to /api/state (scaled 0-100) - React RigScreen now reads real levels from state instead of random walk - When no audio flows, VU meters show flat (0) instead of fake animation
This commit is contained in:
@@ -460,23 +460,11 @@ function SlidePanel({ children, onClose }) {
|
|||||||
// 1. RIG SCREEN ────────────────────────────────────────────────
|
// 1. RIG SCREEN ────────────────────────────────────────────────
|
||||||
function RigScreen({ state, connected }) {
|
function RigScreen({ state, connected }) {
|
||||||
const [volume, setVolume] = useState(state?.master_volume != null ? Math.round(state.master_volume * 100) : 80);
|
const [volume, setVolume] = useState(state?.master_volume != null ? Math.round(state.master_volume * 100) : 80);
|
||||||
const [vuL, setVuL] = useState(45);
|
|
||||||
const [vuR, setVuR] = useState(42);
|
|
||||||
const [saving, setSaving] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state?.master_volume != null) setVolume(Math.round(state.master_volume * 100));
|
if (state?.master_volume != null) setVolume(Math.round(state.master_volume * 100));
|
||||||
}, [state?.master_volume]);
|
}, [state?.master_volume]);
|
||||||
|
|
||||||
// Animated VU
|
|
||||||
useEffect(() => {
|
|
||||||
const id = setInterval(() => {
|
|
||||||
setVuL(prev => Math.max(10, Math.min(95, prev + (Math.random() - 0.48) * 12)));
|
|
||||||
setVuR(prev => Math.max(10, Math.min(95, prev + (Math.random() - 0.48) * 12)));
|
|
||||||
}, 90);
|
|
||||||
return () => clearInterval(id);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleVolume = async (val) => {
|
const handleVolume = async (val) => {
|
||||||
setVolume(val);
|
setVolume(val);
|
||||||
try {
|
try {
|
||||||
@@ -497,6 +485,10 @@ function RigScreen({ state, connected }) {
|
|||||||
} catch (e) { /* ignore */ }
|
} catch (e) { /* ignore */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Real audio levels from the pipeline (0-100 scale, updated every poll cycle)
|
||||||
|
const inputLevel = state?.input_level ?? 0;
|
||||||
|
const outputLevel = state?.output_level ?? 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
|
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
|
||||||
<div className="screen-header">
|
<div className="screen-header">
|
||||||
@@ -518,8 +510,8 @@ function RigScreen({ state, connected }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", gap: 6, alignItems: "center" }}>
|
<div style={{ display: "flex", gap: 6, alignItems: "center" }}>
|
||||||
<VUMeter level={vuL} height={44} />
|
<VUMeter level={inputLevel} height={44} />
|
||||||
<VUMeter level={vuR} height={44} />
|
<VUMeter level={outputLevel} height={44} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="screen-body">
|
<div className="screen-body">
|
||||||
|
|||||||
@@ -1023,6 +1023,8 @@ class WebServer:
|
|||||||
"nam_model": None,
|
"nam_model": None,
|
||||||
"ir_loaded": False,
|
"ir_loaded": False,
|
||||||
"ir_name": None,
|
"ir_name": None,
|
||||||
|
"input_level": 0,
|
||||||
|
"output_level": 0,
|
||||||
"wifi": {},
|
"wifi": {},
|
||||||
"bluetooth": {},
|
"bluetooth": {},
|
||||||
}
|
}
|
||||||
@@ -1065,6 +1067,9 @@ class WebServer:
|
|||||||
"nam_model": current_model_name,
|
"nam_model": current_model_name,
|
||||||
"ir_loaded": bool(ir and ir.is_loaded) if ir else False,
|
"ir_loaded": bool(ir and ir.is_loaded) if ir else False,
|
||||||
"ir_name": current_ir_name,
|
"ir_name": current_ir_name,
|
||||||
|
# Audio levels from pipeline (RMS float32 normalized 0.0-1.0, scaled to 0-100)
|
||||||
|
"input_level": min(100, round((pl._input_level or 0.0) * 150)) if pl else 0,
|
||||||
|
"output_level": min(100, round((pl._output_level or 0.0) * 150)) if pl else 0,
|
||||||
"wifi": self._gather_wifi_state(),
|
"wifi": self._gather_wifi_state(),
|
||||||
"bluetooth": self._gather_bt_state(),
|
"bluetooth": self._gather_bt_state(),
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/ui/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/ui/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Pi Multi-FX Pedal</title>
|
<title>Pi Multi-FX Pedal</title>
|
||||||
<script type="module" crossorigin src="/ui/assets/index-3XaYhUGn.js"></script>
|
<script type="module" crossorigin src="/ui/assets/index-By7LnVlV.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/ui/assets/index-CuJgR-s6.css">
|
<link rel="stylesheet" crossorigin href="/ui/assets/index-CuJgR-s6.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user