content/media/webaudio/test/test_delayNodeTailWithReconnect.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <head>
michael@0 4 <title>Test tail time lifetime of DelayNode after input finishes and new input added</title>
michael@0 5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
michael@0 6 <script type="text/javascript" src="webaudio.js"></script>
michael@0 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
michael@0 8 </head>
michael@0 9 <body>
michael@0 10 <pre id="test">
michael@0 11 <script class="testbody" type="text/javascript">
michael@0 12
michael@0 13 SimpleTest.waitForExplicitFinish();
michael@0 14
michael@0 15 // The buffer source will start on a block boundary, so keeping the signal
michael@0 16 // within one block ensures that it will not cross AudioProcessingEvent buffer
michael@0 17 // boundaries.
michael@0 18 const signalLength = 128;
michael@0 19 const bufferSize = 1024;
michael@0 20 // Delay should be long enough to allow CC to run
michael@0 21 var delayBufferCount = 50;
michael@0 22 var delayBufferOffset;
michael@0 23 const delayLength = delayBufferCount * bufferSize;
michael@0 24
michael@0 25 var phase = "initial";
michael@0 26 var sourceCount = 0;
michael@0 27 var delayCount = 0;
michael@0 28 var oscillator;
michael@0 29 var delay;
michael@0 30 var source;
michael@0 31
michael@0 32 function applySignal(buffer, offset) {
michael@0 33 for (var i = 0; i < signalLength; ++i) {
michael@0 34 buffer.getChannelData(0)[offset + i] = Math.cos(Math.PI * i / signalLength);
michael@0 35 }
michael@0 36 }
michael@0 37
michael@0 38 function bufferIsSilent(buffer, out) {
michael@0 39 for (var i = 0; i < buffer.length; ++i) {
michael@0 40 if (buffer.getChannelData(0)[i] != 0) {
michael@0 41 if (out) {
michael@0 42 out.soundOffset = i;
michael@0 43 }
michael@0 44 return false;
michael@0 45 }
michael@0 46 }
michael@0 47 return true;
michael@0 48 }
michael@0 49
michael@0 50 function onDelayOutput(e) {
michael@0 51 switch(phase) {
michael@0 52
michael@0 53 case "initial":
michael@0 54 // Wait for oscillator sound to exit delay
michael@0 55 if (bufferIsSilent(e.inputBuffer))
michael@0 56 break;
michael@0 57
michael@0 58 phase = "played oscillator";
michael@0 59 break;
michael@0 60
michael@0 61 case "played oscillator":
michael@0 62 // First tail time has expired. Start second source and remove references
michael@0 63 // to the delay and connected second source.
michael@0 64 oscillator.disconnect();
michael@0 65 source.connect(delay);
michael@0 66 source.start();
michael@0 67 source = null;
michael@0 68 delay = null;
michael@0 69 phase = "started second source";
michael@0 70 break;
michael@0 71
michael@0 72 case "second tail time":
michael@0 73 if (delayCount == delayBufferCount) {
michael@0 74 var ctx = e.target.context;
michael@0 75 var expected = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
michael@0 76 applySignal(expected, delayBufferOffset);
michael@0 77 compareBuffers(e.inputBuffer, expected);
michael@0 78 e.target.onaudioprocess = null;
michael@0 79 SimpleTest.finish();
michael@0 80 }
michael@0 81 }
michael@0 82
michael@0 83 delayCount++;
michael@0 84 }
michael@0 85
michael@0 86 function onSourceOutput(e) {
michael@0 87 switch(phase) {
michael@0 88 case "started second source":
michael@0 89 var out = {};
michael@0 90 if (!bufferIsSilent(e.inputBuffer, out)) {
michael@0 91 delayBufferCount += sourceCount;
michael@0 92 delayBufferOffset = out.soundOffset;
michael@0 93 phase = "played second source";
michael@0 94 }
michael@0 95 break;
michael@0 96 case "played second source":
michael@0 97 SpecialPowers.forceGC();
michael@0 98 SpecialPowers.forceCC();
michael@0 99 phase = "second tail time";
michael@0 100 e.target.onaudioprocess = null;
michael@0 101 }
michael@0 102
michael@0 103 sourceCount++;
michael@0 104 }
michael@0 105
michael@0 106 function startTest() {
michael@0 107 var ctx = new AudioContext();
michael@0 108 var delayDuration = delayLength / ctx.sampleRate;
michael@0 109 delay = ctx.createDelay(delayDuration);
michael@0 110 delay.delayTime.value = delayDuration;
michael@0 111 var processor1 = ctx.createScriptProcessor(bufferSize, 1, 0);
michael@0 112 delay.connect(processor1);
michael@0 113 processor1.onaudioprocess = onDelayOutput;
michael@0 114 processor1.connect(ctx.destination); // work around bug 916387
michael@0 115
michael@0 116 // Signal to trigger initial tail time reference
michael@0 117 oscillator = ctx.createOscillator();
michael@0 118 oscillator.start(0);
michael@0 119 oscillator.stop(100/ctx.sampleRate);
michael@0 120 oscillator.connect(delay);
michael@0 121
michael@0 122 // Short signal, not started yet, with a ScriptProcessor to detect when it
michael@0 123 // starts. It should finish before garbage collection.
michael@0 124 var buffer = ctx.createBuffer(1, signalLength, ctx.sampleRate);
michael@0 125 applySignal(buffer, 0);
michael@0 126 source = ctx.createBufferSource();
michael@0 127 source.buffer = buffer;
michael@0 128 var processor2 = ctx.createScriptProcessor(bufferSize, 1, 0);
michael@0 129 source.connect(processor2);
michael@0 130 processor2.onaudioprocess = onSourceOutput;
michael@0 131 processor2.connect(ctx.destination); // guard against bug 916387
michael@0 132 };
michael@0 133
michael@0 134 startTest();
michael@0 135 </script>
michael@0 136 </pre>
michael@0 137 </body>
michael@0 138 </html>

mercurial