feat: relay station masts come online through the toolkit chapter
This commit is contained in:
45
src/audio/relay-tone.ts
Normal file
45
src/audio/relay-tone.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { readSwitchboard } from '@/audio/music-pulse';
|
||||
|
||||
/** Tone length, seconds. */
|
||||
export const RELAY_TONE_SECONDS = 0.12;
|
||||
export const RELAY_TONE_GAIN = 0.12;
|
||||
/** At most one tone every 0.6 s, however fast the scroll. */
|
||||
export const RELAY_TONE_GAP_SECONDS = 0.6;
|
||||
|
||||
let lastStart = Number.NEGATIVE_INFINITY;
|
||||
|
||||
/**
|
||||
* RELAY STATION: a mast coming online chirps once, a 120 ms sine rising
|
||||
* 880 -> 1320 Hz, through the switchboard (mix bus) so mute and volume
|
||||
* apply. Lazy-loaded by the scene; plays only while the soundtrack is
|
||||
* running and audible; never creates an AudioContext and never throws.
|
||||
*/
|
||||
export function playRelayTone(): boolean {
|
||||
try {
|
||||
const input = readSwitchboard();
|
||||
if (input === null || input.context.state !== 'running') return false;
|
||||
const context = input.context;
|
||||
const start = context.currentTime + 0.005;
|
||||
if (start - lastStart < RELAY_TONE_GAP_SECONDS) return false;
|
||||
lastStart = start;
|
||||
const osc = context.createOscillator();
|
||||
osc.type = 'sine';
|
||||
osc.frequency.setValueAtTime(880, start);
|
||||
osc.frequency.exponentialRampToValueAtTime(1320, start + RELAY_TONE_SECONDS);
|
||||
const envelope = context.createGain();
|
||||
envelope.gain.setValueAtTime(0, start);
|
||||
envelope.gain.linearRampToValueAtTime(RELAY_TONE_GAIN, start + 0.01);
|
||||
envelope.gain.exponentialRampToValueAtTime(0.0002, start + RELAY_TONE_SECONDS);
|
||||
osc.connect(envelope);
|
||||
envelope.connect(input);
|
||||
osc.onended = () => {
|
||||
osc.disconnect();
|
||||
envelope.disconnect();
|
||||
};
|
||||
osc.start(start);
|
||||
osc.stop(start + RELAY_TONE_SECONDS + 0.01);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user