audiocontext-suspend-resume.html (4226B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> 5 Test AudioContext.suspend() and AudioContext.resume() 6 </title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 </head> 10 <body> 11 <script> 12 13 const sampleRate = 44100; 14 const durationInSeconds = 1; 15 16 // Task: test suspend(). 17 promise_test(async t => { 18 // Create an audio context with an oscillator. 19 const offlineContext = new OfflineAudioContext( 20 1, durationInSeconds * sampleRate, sampleRate); 21 const osc = new OscillatorNode(offlineContext); 22 osc.connect(offlineContext.destination); 23 24 // Verify the state. 25 assert_equals( 26 offlineContext.state, 'suspended', 27 'offlineContext.state should start as "suspended"'); 28 29 // Multiple calls to suspend() should not be a problem, but we can’t 30 // test that on an offline context. Thus, check that suspend() on an 31 // OfflineAudioContext rejects the promise. 32 const p1 = offlineContext.suspend(); 33 assert_true(p1 instanceof Promise, 'p1 is a Promise'); 34 35 let rejected = false; 36 await p1.then( 37 () => assert_unreached('offlineContext.suspend() should reject'), 38 () => { rejected = true; }); 39 assert_true(rejected, 'suspend() promise was rejected as expected'); 40 }, 'Test suspend() for offline context'); 41 42 // Task: test resume(). 43 promise_test(async t => { 44 // Multiple calls to resume() should not be a problem, but we can’t 45 // test that on an offline context. Thus, check that resume() on an 46 // OfflineAudioContext rejects the promise. 47 const offlineContext = new OfflineAudioContext( 48 1, durationInSeconds * sampleRate, sampleRate); 49 const p2 = offlineContext.resume(); 50 assert_true(p2 instanceof Promise, 'p2 is a Promise'); 51 52 // resume() doesn’t actually resume an offline context. 53 assert_equals( 54 offlineContext.state, 'suspended', 55 'State after resume() is still "suspended"'); 56 57 let rejected = false; 58 await p2.then( 59 () => assert_unreached('offlineContext.resume() should reject'), 60 () => { rejected = true; }); 61 assert_true(rejected, 'resume() promise was rejected as expected'); 62 }, 'Test resume() for offline context'); 63 64 // Task 3: test the state after context closed. 65 promise_test(async t => { 66 // Render the offline context. 67 const offlineContext = new OfflineAudioContext( 68 1, durationInSeconds * sampleRate, sampleRate); 69 const osc = new OscillatorNode(offlineContext); 70 osc.connect(offlineContext.destination); 71 osc.start(); 72 73 // We don’t care about the actual rendering result. 74 await offlineContext.startRendering(); 75 76 // After rendering, the context should be closed. 77 assert_equals( 78 offlineContext.state, 'closed', 79 'offlineContext.state should be "closed" after rendering'); 80 81 // suspend() should be rejected on a closed context. 82 await offlineContext.suspend().then( 83 () => assert_unreached('suspend() on closed context should reject'), 84 () => { /* expected */ }); 85 86 // resume() should be rejected on a closed context. 87 await offlineContext.resume().then( 88 () => assert_unreached('resume() on closed context should reject'), 89 () => { /* expected */ }); 90 }, 'Test state after context closed'); 91 92 // Task: resume a running AudioContext. 93 promise_test(async t => { 94 // Ideally this test is best with an online AudioContext, but content 95 // shell doesn’t really have a working online AudioContext. 96 // Nonetheless, create one and check resume(). 97 const context = new AudioContext(); 98 assert_equals(context.state, 'suspended', 'Initial state is suspended'); 99 100 await context.resume(); 101 assert_equals( 102 context.state, 'running', 'State after resume is running'); 103 }, 'Test resuming a running online context'); 104 </script> 105 </body> 106 </html>