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
|
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
<head>
<title>Test that MediaStreamAudioSourceNode and its input MediaStream stays alive while there are active tracks</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("gUM and WebAudio data is async to main thread. " +
"We need a timeout to see that something does " +
"NOT happen to data.");
var context = new AudioContext();
var analyser = context.createAnalyser();
function wait(millis, resolveWithThis) {
return new Promise(resolve => setTimeout(() => resolve(resolveWithThis), millis));
}
function binIndexForFrequency(frequency) {
return 1 + Math.round(frequency * analyser.fftSize / context.sampleRate);
}
function waitForAudio(analysisFunction, cancelPromise) {
var data = new Uint8Array(analyser.frequencyBinCount);
var cancelled = false;
var cancelledMsg = "";
cancelPromise.then(msg => {
cancelled = true;
cancelledMsg = msg;
});
return new Promise((resolve, reject) => {
var loop = () => {
analyser.getByteFrequencyData(data);
if (cancelled) {
reject(new Error("waitForAudio cancelled: " + cancelledMsg));
return;
}
if (analysisFunction(data)) {
resolve();
return;
}
requestAnimationFrame(loop);
};
loop();
});
}
navigator.mediaDevices.getUserMedia({audio: true, fake: true})
.then(stream => {
stream.onended = () => ended = true;
let source = context.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(context.destination);
})
.then(() => {
ok(true, "Waiting for audio to pass through the analyser")
return waitForAudio(arr => arr[binIndexForFrequency(1000)] > 200,
wait(60000, "Timeout waiting for audio"));
})
.then(() => {
ok(true, "Audio was detected by the analyser. Forcing CC.");
SpecialPowers.forceCC();
SpecialPowers.forceGC();
SpecialPowers.forceCC();
SpecialPowers.forceGC();
info("Checking that GC didn't destroy the stream or source node");
return waitForAudio(arr => arr[binIndexForFrequency(1000)] < 50,
wait(5000, "Timeout waiting for GC (timeout OK)"))
.then(() => Promise.reject("Audio stopped unexpectedly"),
() => Promise.resolve());
})
.then(() => {
ok(true, "Audio is still flowing");
SimpleTest.finish();
})
.catch(e => {
ok(false, "Error executing test: " + e + (e.stack ? "\n" + e.stack : ""));
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>
|