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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
var Analyser = function(type, twist, elContainer, csApp) {
var self = this;
var scopeNode = twirl.audioContext.createAnalyser();
var node;
var elCanvas = $("<canvas />").css({
position: "absolute",
width: "100%",
height: "100%",
top: "0px",
left: "0px"
}).addClass("twist_scope").appendTo(elContainer);
var context = elCanvas[0].getContext("2d");
var playing = false;
this.remove = function() {
type = null;
elContainer.remove();
};
function frequency() {
if (type != 0 || !playing) return;
let style = getComputedStyle(document.body);
let width = elCanvas[0].width = elContainer.width();
let height = elCanvas[0].height = elContainer.height();
let freqData = new Uint8Array(scopeNode.frequencyBinCount);
let scaling = height / 256;
scopeNode.getByteFrequencyData(freqData);
context.fillStyle = style.getPropertyValue("--waveformBgColor");
context.fillRect(0, 0, width, height);
context.lineWidth = 2;
context.strokeStyle = style.getPropertyValue("--waveformFgColor");
context.beginPath();
for (var x = 0; x < width; x++) {
context.lineTo(x, height - freqData[x] * scaling);
}
context.stroke();
requestAnimationFrame(frequency);
}
function oscilloscope() {
if (type != 1 || !playing) return;
let style = getComputedStyle(document.body);
let width = elCanvas[0].width = elContainer.width();
let height = elCanvas[0].height = elContainer.height();
let timeData = new Uint8Array(scopeNode.frequencyBinCount);
let scaling = height / 256;
let risingEdge = 0;
let edgeThreshold = 5;
scopeNode.getByteTimeDomainData(timeData);
context.fillStyle = style.getPropertyValue("--waveformBgColor");
context.fillRect(0, 0, width, height);
context.lineWidth = 2;
context.strokeStyle = style.getPropertyValue("--waveformFgColor");
context.beginPath();
while (timeData[risingEdge++] - 128 > 0 && risingEdge <= width);
if (risingEdge >= width) risingEdge = 0;
while (timeData[risingEdge++] - 128 < edgeThreshold && risingEdge <= width);
if (risingEdge >= width) risingEdge = 0;
for (var x = risingEdge; x < timeData.length && x - risingEdge < width; x++) {
context.lineTo(x - risingEdge, height - timeData[x] * scaling);
}
context.stroke();
requestAnimationFrame(oscilloscope);
}
this.setPlaying = function(state) {
playing = state;
if (playing) {
if (type == 0) {
frequency();
} else if (type == 1) {
oscilloscope();
}
}
};
this.setType = function(v) {
type = v;
self.setPlaying(playing);
};
async function boot() {
node = await csApp.getNode();
node.connect(scopeNode);
if (twist.isPlaying()) {
self.setPlaying(true);
}
}
boot();
};
|