PageSourceSearch

https://warriorlifepodcast.com/demo/demo-audio.js?v=43193240f6b6

js warriorlifepodcast.com collected 2026-10-09 01:09:38 UTC 3,031 bytes, 79 lines download raw bytes

1/* Speaker-only synthetic tones. No microphone, files, network, or radio output. */
2(() => {
3  "use strict";
4  class DemoAudio {
5    constructor(clock, isPaused) {
6      this.clock = clock;
7      this.isPaused = isPaused;
8      this.enabled = false;
9      this.volume = .25;
10      this.context = null;
11      this.voices = [];
12      this.timer = null;
13    }
14    async setEnabled(enabled) {
15      this.enabled = Boolean(enabled);
16      if (!this.enabled) { this.update(); return false; }
17      try {
18        if (!this.context) {
19          const Audio = window.AudioContext || window.webkitAudioContext;
20          if (!Audio) throw new Error("Sound is unavailable in this browser");
21          this.context = new Audio();
22          this.master = this.context.createGain();
23          this.master.gain.value = 0;
24          this.master.connect(this.context.destination);
25          for (let index = 0; index < 8; index++) {
26            const oscillator = this.context.createOscillator();
27            const gain = this.context.createGain();
28            oscillator.type = "sine";
29            gain.gain.value = 0;
30            oscillator.connect(gain);
31            gain.connect(this.master);
32            oscillator.start();
33            this.voices.push({oscillator, gain});
34          }
35          this.timer = setInterval(() => this.update(), 50);
36        }
37        await this.context.resume();
38        this.update();
39        return this.enabled;
40      } catch (error) {
41        this.dispose();
42        throw error;
43      }
44    }
45    setVolume(value) {
46      const number = Number(value);
47      this.volume = Number.isFinite(number) ? Math.max(0, Math.min(1, number)) : 0;
48      this.update();
49    }
50    update() {
51      if (!this.context) return;
52      const time = this.context.currentTime;
53      const audible = this.enabled && !this.isPaused() && !document.hidden;
54      this.master.gain.setTargetAtTime(audible ? this.volume : 0, time, .01);
55      this.voices.forEach(({oscillator, gain}, index) => {
56        const station = window.dccDemoStation?.snapshot();
57        const tx = station?.tuning || station?.transmitting;
58        const signal = !audible ? null : tx ? (index === 0 ? {
59          hz: station.audioHz + (station.tuning ? 0 : (Math.floor(this.clock() / .16) % 8) * 6.25), amplitude: .65
60        } : null) : station?.monitoring === false ? null : window.dccDemoWaterfall.signalAt(this.clock(), index);
61        if (signal) oscillator.frequency.setTargetAtTime(signal.hz, time, .008);
62        gain.gain.setTargetAtTime(signal ? signal.amplitude * .12 : 0, time, .01);
63      });
64    }
65    dispose() {
66      this.enabled = false;
67      if (this.timer !== null) clearInterval(this.timer);
68      this.timer = null;
69      if (this.context) {
70        this.master?.gain.setValueAtTime(0, this.context.currentTime);
71        this.voices.forEach(({oscillator}) => oscillator.stop());
72        this.context.close().catch(() => {});
73      }
74      this.context = null;
75      this.voices = [];
76    }
77  }
78  window.DccDemoAudio = DemoAudio;
79})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.