Fix fading to silent, and PFL metering.

This commit is contained in:
Matthew Stratford 2021-01-24 21:43:51 +00:00
parent ed8e27547f
commit 9319eb49b7
2 changed files with 15 additions and 9 deletions

View file

@ -8,6 +8,7 @@ import NewsEndCountdown from "../assets/audio/NewsEndCountdown.wav";
import NewsIntro from "../assets/audio/NewsIntro.wav"; import NewsIntro from "../assets/audio/NewsIntro.wav";
import StereoAnalyserNode from "stereo-analyser-node"; import StereoAnalyserNode from "stereo-analyser-node";
import { DEFAULT_TRIM_DB, OFF_LEVEL_DB } from "./state";
interface PlayerEvents { interface PlayerEvents {
loadComplete: (duration: number) => void; loadComplete: (duration: number) => void;
@ -164,8 +165,10 @@ class Player extends ((PlayerEmitter as unknown) as { new (): EventEmitter }) {
} }
_applyVolume() { _applyVolume() {
const level = this.volume + this.trim; const log = this.volume + this.trim;
const linear = Math.pow(10, level / 20);
// 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. // Actually adjust the wavesurfer gain node gain instead, so we can tap off analyser for PFL.
this.wavesurfer.setVolume(1); this.wavesurfer.setVolume(1);
@ -461,7 +464,7 @@ export class AudioEngine extends ((EngineEmitter as unknown) as {
this.newsEndCountdownNode.connect(this.audioContext.destination); this.newsEndCountdownNode.connect(this.audioContext.destination);
// Send the headphones feed to the headphones. // 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.gain.value = Math.pow(10, db / 20);
this.headphonesNode.connect(this.audioContext.destination); this.headphonesNode.connect(this.audioContext.destination);
this.headphonesNode.connect(this.pflAnalyser); this.headphonesNode.connect(this.pflAnalyser);

View file

@ -28,8 +28,11 @@ type VolumePresetEnum = "off" | "bed" | "full";
type MicVolumePresetEnum = "off" | "full"; type MicVolumePresetEnum = "off" | "full";
export type MicErrorEnum = "NO_PERMISSION" | "NOT_SECURE_CONTEXT" | "UNKNOWN"; 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 { interface PlayerState {
loadedItem: PlanItem | Track | AuxItem | null; loadedItem: PlanItem | Track | AuxItem | null;
loading: number; loading: number;
@ -72,7 +75,7 @@ const BasePlayerState: PlayerState = {
volumeEnum: "full", volumeEnum: "full",
gain: 0, gain: 0,
micAutoDuck: false, micAutoDuck: false,
trim: defaultTrimDB, trim: DEFAULT_TRIM_DB,
pfl: false, pfl: false,
timeCurrent: 0, timeCurrent: 0,
timeRemaining: 0, timeRemaining: 0,
@ -125,7 +128,7 @@ const mixerState = createSlice({
if (action.payload.customOutput) { if (action.payload.customOutput) {
state.players[action.payload.player].trim = 0; state.players[action.payload.player].trim = 0;
} else if (action.payload.resetTrim) { } else if (action.payload.resetTrim) {
state.players[action.payload.player].trim = defaultTrimDB; state.players[action.payload.player].trim = DEFAULT_TRIM_DB;
} }
}, },
itemLoadPercentage( itemLoadPercentage(
@ -702,15 +705,15 @@ export const setVolume = (
let uiLevel: number; let uiLevel: number;
switch (level) { switch (level) {
case "off": case "off":
volume = -40; volume = OFF_LEVEL_DB; // The sweet spot for getting below the silence rounding in audio.ts -> _applyVolume()
uiLevel = 0; uiLevel = 0;
break; break;
case "bed": case "bed":
volume = -13; volume = BED_LEVEL_DB;
uiLevel = 0.5; uiLevel = 0.5;
break; break;
case "full": case "full":
volume = 0; volume = FULL_LEVEL_DB;
uiLevel = 1; uiLevel = 1;
break; break;
} }