1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/webaudio/test/test_delayNodeTailWithReconnect.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,138 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<head> 1.7 + <title>Test tail time lifetime of DelayNode after input finishes and new input added</title> 1.8 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.9 + <script type="text/javascript" src="webaudio.js"></script> 1.10 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.11 +</head> 1.12 +<body> 1.13 +<pre id="test"> 1.14 +<script class="testbody" type="text/javascript"> 1.15 + 1.16 +SimpleTest.waitForExplicitFinish(); 1.17 + 1.18 +// The buffer source will start on a block boundary, so keeping the signal 1.19 +// within one block ensures that it will not cross AudioProcessingEvent buffer 1.20 +// boundaries. 1.21 +const signalLength = 128; 1.22 +const bufferSize = 1024; 1.23 +// Delay should be long enough to allow CC to run 1.24 +var delayBufferCount = 50; 1.25 +var delayBufferOffset; 1.26 +const delayLength = delayBufferCount * bufferSize; 1.27 + 1.28 +var phase = "initial"; 1.29 +var sourceCount = 0; 1.30 +var delayCount = 0; 1.31 +var oscillator; 1.32 +var delay; 1.33 +var source; 1.34 + 1.35 +function applySignal(buffer, offset) { 1.36 + for (var i = 0; i < signalLength; ++i) { 1.37 + buffer.getChannelData(0)[offset + i] = Math.cos(Math.PI * i / signalLength); 1.38 + } 1.39 +} 1.40 + 1.41 +function bufferIsSilent(buffer, out) { 1.42 + for (var i = 0; i < buffer.length; ++i) { 1.43 + if (buffer.getChannelData(0)[i] != 0) { 1.44 + if (out) { 1.45 + out.soundOffset = i; 1.46 + } 1.47 + return false; 1.48 + } 1.49 + } 1.50 + return true; 1.51 +} 1.52 + 1.53 +function onDelayOutput(e) { 1.54 + switch(phase) { 1.55 + 1.56 + case "initial": 1.57 + // Wait for oscillator sound to exit delay 1.58 + if (bufferIsSilent(e.inputBuffer)) 1.59 + break; 1.60 + 1.61 + phase = "played oscillator"; 1.62 + break; 1.63 + 1.64 + case "played oscillator": 1.65 + // First tail time has expired. Start second source and remove references 1.66 + // to the delay and connected second source. 1.67 + oscillator.disconnect(); 1.68 + source.connect(delay); 1.69 + source.start(); 1.70 + source = null; 1.71 + delay = null; 1.72 + phase = "started second source"; 1.73 + break; 1.74 + 1.75 + case "second tail time": 1.76 + if (delayCount == delayBufferCount) { 1.77 + var ctx = e.target.context; 1.78 + var expected = ctx.createBuffer(1, bufferSize, ctx.sampleRate); 1.79 + applySignal(expected, delayBufferOffset); 1.80 + compareBuffers(e.inputBuffer, expected); 1.81 + e.target.onaudioprocess = null; 1.82 + SimpleTest.finish(); 1.83 + } 1.84 + } 1.85 + 1.86 + delayCount++; 1.87 +} 1.88 + 1.89 +function onSourceOutput(e) { 1.90 + switch(phase) { 1.91 + case "started second source": 1.92 + var out = {}; 1.93 + if (!bufferIsSilent(e.inputBuffer, out)) { 1.94 + delayBufferCount += sourceCount; 1.95 + delayBufferOffset = out.soundOffset; 1.96 + phase = "played second source"; 1.97 + } 1.98 + break; 1.99 + case "played second source": 1.100 + SpecialPowers.forceGC(); 1.101 + SpecialPowers.forceCC(); 1.102 + phase = "second tail time"; 1.103 + e.target.onaudioprocess = null; 1.104 + } 1.105 + 1.106 + sourceCount++; 1.107 +} 1.108 + 1.109 +function startTest() { 1.110 + var ctx = new AudioContext(); 1.111 + var delayDuration = delayLength / ctx.sampleRate; 1.112 + delay = ctx.createDelay(delayDuration); 1.113 + delay.delayTime.value = delayDuration; 1.114 + var processor1 = ctx.createScriptProcessor(bufferSize, 1, 0); 1.115 + delay.connect(processor1); 1.116 + processor1.onaudioprocess = onDelayOutput; 1.117 + processor1.connect(ctx.destination); // work around bug 916387 1.118 + 1.119 + // Signal to trigger initial tail time reference 1.120 + oscillator = ctx.createOscillator(); 1.121 + oscillator.start(0); 1.122 + oscillator.stop(100/ctx.sampleRate); 1.123 + oscillator.connect(delay); 1.124 + 1.125 + // Short signal, not started yet, with a ScriptProcessor to detect when it 1.126 + // starts. It should finish before garbage collection. 1.127 + var buffer = ctx.createBuffer(1, signalLength, ctx.sampleRate); 1.128 + applySignal(buffer, 0); 1.129 + source = ctx.createBufferSource(); 1.130 + source.buffer = buffer; 1.131 + var processor2 = ctx.createScriptProcessor(bufferSize, 1, 0); 1.132 + source.connect(processor2); 1.133 + processor2.onaudioprocess = onSourceOutput; 1.134 + processor2.connect(ctx.destination); // guard against bug 916387 1.135 +}; 1.136 + 1.137 +startTest(); 1.138 +</script> 1.139 +</pre> 1.140 +</body> 1.141 +</html>