From 9319eb49b78a34b4c9a7a5d5a6ba7d95c430424f Mon Sep 17 00:00:00 2001 From: Matthew Stratford Date: Sun, 24 Jan 2021 21:43:51 +0000 Subject: [PATCH] Fix fading to silent, and PFL metering. --- src/mixer/audio.ts | 9 ++++++--- src/mixer/state.ts | 15 +++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/mixer/audio.ts b/src/mixer/audio.ts index 14c25a4..900ef3a 100644 --- a/src/mixer/audio.ts +++ b/src/mixer/audio.ts @@ -8,6 +8,7 @@ import NewsEndCountdown from "../assets/audio/NewsEndCountdown.wav"; import NewsIntro from "../assets/audio/NewsIntro.wav"; import StereoAnalyserNode from "stereo-analyser-node"; +import { DEFAULT_TRIM_DB, OFF_LEVEL_DB } from "./state"; interface PlayerEvents { loadComplete: (duration: number) => void; @@ -164,8 +165,10 @@ class Player extends ((PlayerEmitter as unknown) as { new (): EventEmitter }) { } _applyVolume() { - const level = this.volume + this.trim; - const linear = Math.pow(10, level / 20); + const log = this.volume + this.trim; + + // If we're down at the "off level", pure mute it, else, do the linear conversion. + let linear = this.volume === OFF_LEVEL_DB ? 0 : Math.pow(10, log / 20); // Actually adjust the wavesurfer gain node gain instead, so we can tap off analyser for PFL. this.wavesurfer.setVolume(1); @@ -461,7 +464,7 @@ export class AudioEngine extends ((EngineEmitter as unknown) as { this.newsEndCountdownNode.connect(this.audioContext.destination); // Send the headphones feed to the headphones. - const db = -12; // DB gain on headphones (-6 to match default trim) + const db = DEFAULT_TRIM_DB; // DB gain on headphones (match default trim) this.headphonesNode.gain.value = Math.pow(10, db / 20); this.headphonesNode.connect(this.audioContext.destination); this.headphonesNode.connect(this.pflAnalyser); diff --git a/src/mixer/state.ts b/src/mixer/state.ts index 48c95b7..3081d89 100644 --- a/src/mixer/state.ts +++ b/src/mixer/state.ts @@ -28,8 +28,11 @@ type VolumePresetEnum = "off" | "bed" | "full"; type MicVolumePresetEnum = "off" | "full"; export type MicErrorEnum = "NO_PERMISSION" | "NOT_SECURE_CONTEXT" | "UNKNOWN"; -const defaultTrimDB = -6; // The default trim applied to channel players. +export const DEFAULT_TRIM_DB = -6; // The default trim applied to channel players. +export const OFF_LEVEL_DB = -40; +export const BED_LEVEL_DB = -13; +export const FULL_LEVEL_DB = 0; interface PlayerState { loadedItem: PlanItem | Track | AuxItem | null; loading: number; @@ -72,7 +75,7 @@ const BasePlayerState: PlayerState = { volumeEnum: "full", gain: 0, micAutoDuck: false, - trim: defaultTrimDB, + trim: DEFAULT_TRIM_DB, pfl: false, timeCurrent: 0, timeRemaining: 0, @@ -125,7 +128,7 @@ const mixerState = createSlice({ if (action.payload.customOutput) { state.players[action.payload.player].trim = 0; } else if (action.payload.resetTrim) { - state.players[action.payload.player].trim = defaultTrimDB; + state.players[action.payload.player].trim = DEFAULT_TRIM_DB; } }, itemLoadPercentage( @@ -702,15 +705,15 @@ export const setVolume = ( let uiLevel: number; switch (level) { case "off": - volume = -40; + volume = OFF_LEVEL_DB; // The sweet spot for getting below the silence rounding in audio.ts -> _applyVolume() uiLevel = 0; break; case "bed": - volume = -13; + volume = BED_LEVEL_DB; uiLevel = 0.5; break; case "full": - volume = 0; + volume = FULL_LEVEL_DB; uiLevel = 1; break; }