Give Sound the whole story, and keep the buttons inside the card

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 11:39:16 -04:00
parent 9bc68ba358
commit b58371bb35
38 changed files with 3884 additions and 213 deletions
@@ -75,6 +75,21 @@ ShellRoot {
return AudioStreams.group(fixtureNodes, audioOutStreamFlag);
}
// A throwaway two-stream group for the clamp cases. The shared fixture
// above is mutated by the volume and mute tests, and a clamp assertion that
// depended on which of those ran first would be worthless.
function clampFixture(): var {
return {
key: "clamp",
label: "Clamp",
icon: "audio-x-generic-symbolic",
nodes: [
{ audio: { volume: 0.1, muted: true } },
{ audio: { volume: 0.1, muted: true } }
]
};
}
IpcHandler {
target: "application-volume-test"
@@ -115,6 +130,31 @@ ShellRoot {
});
}
// Over-amplification is a preference, so the ceiling is an argument
// rather than a constant -- this file stays Settings-free on purpose.
function clampVolume(): string {
const overAmp = clampFixture();
const overAmpChanged = AudioStreams.setVolume(overAmp, 1.4, 1.5);
const ceiling = clampFixture();
AudioStreams.setVolume(ceiling, 2.5, 1.5);
const defaultMax = clampFixture();
AudioStreams.setVolume(defaultMax, 1.4);
const floor = clampFixture();
AudioStreams.setVolume(floor, -0.5, 1.5);
const nonNumeric = clampFixture();
const nonNumericChanged = AudioStreams.setVolume(nonNumeric, "loud", 1.5);
return JSON.stringify({
overAmpChanged,
overAmp: overAmp.nodes.map(node => node.audio.volume),
overAmpMuted: overAmp.nodes.map(node => node.audio.muted),
ceiling: ceiling.nodes.map(node => node.audio.volume),
defaultMax: defaultMax.nodes.map(node => node.audio.volume),
floor: floor.nodes.map(node => node.audio.volume),
nonNumericChanged,
nonNumeric: nonNumeric.nodes.map(node => node.audio.volume)
});
}
function serviceSummary(): string {
const applications = AudioDevices.applications;
return JSON.stringify({