-
Notifications
You must be signed in to change notification settings - Fork 4
/
apple_audio.js
60 lines (52 loc) · 1.72 KB
/
apple_audio.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//
// apple2e audio output device
//
// Copyright 2018, John Clark
//
// Released under the GNU General Public License
// https://www.gnu.org/licenses/gpl.html
//
// ref: https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
// https://github.com/WebKit/webkit/tree/master/Source/WebCore/Modules/webaudio
//
export class AppleAudio
{
constructor(khz) {
this.ac;
this.gn;
this.cpu_hz = khz * 1000;
this.seg_time = 0;
this.seg_clock = 0;
this.state = false;
this.level = 0.6;
}
init() {
if(this.ac) return;
this.ac = new (window.AudioContext || window.webkitAudioContext)();
const osc = this.ac.createOscillator({channelCount:1, channelCountMode:"explicit", frequency:0});
const ws = this.ac.createWaveShaper({channelCount:1, channelCountMode:"explicit"});
ws.curve = new Float32Array([-1, -1]);
this.gn = this.ac.createGain({channelCount:1, channelCountMode:"explicit", gain:0});
osc.connect(ws);
ws.connect(this.gn);
this.gn.connect(this.ac.destination);
osc.start();
}
begin_segment(clock) {
if((this.level == 0) || !this.ac) return;
this.seg_time = this.ac.currentTime + 0.08; // gameplay is in the future
this.seg_clock = clock;
}
click(clock) {
if((this.level == 0) || !this.gn) return;
this.state = !this.state;
const time = (clock - this.seg_clock) / this.cpu_hz;
this.gn.gain.setValueAtTime(this.state ? this.level : 0, time + this.seg_time);
}
reset() {
if(!this.gn) return;
this.state = false;
this.gn.gain.cancelScheduledValues(0);
this.gn.gain.value = 0;
}
}