c32f996f479757599d9c987aa400b824d8709272
[WebKit-https.git] / LayoutTests / webaudio / audiobuffersource-playbackState.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3 <head>
4 <script src="resources/audio-testing.js"></script>
5 <script src="../fast/js/resources/js-test-pre.js"></script>
6 </head>
7
8 <body>
9 <div id="description"></div>
10 <div id="console"></div>
11
12 <script>
13 description("Test AudioContext activeSourceCount and AudioBufferSourceNode playbackState.");
14
15 // Create a few sources that start and end playing at various times.  After rendering, check that
16 // each source is in the correct state and that the number of active sources is correct.
17
18 var sampleRate = 44100;
19
20 // Render for this long.
21 var renderTime = 2;
22 var renderLength = timeToSampleFrame(renderTime, sampleRate);
23
24 var context;
25
26 // List of AudioBufferSourceNodes sources.
27 var sources = [];
28
29 // List of messages that will be printed out on success (or failure).  Messages are in the same
30 // order as the sources list above.
31 var sourceMessages = [];
32
33 // List of the expected playback state for each source.  In the same order a sources list above.
34 var sourceExpectedStates = [];
35
36 // Array mapping the playback state to a string.
37 var playbackStateName = ["UNSCHEDULED_STATE ",
38                          "SCHEDULED_STATE   ",
39                          "PLAYING_STATE     ",
40                          "FINISHED_STATE    "];
41
42 function checkResult(event)
43 {
44     var success = true;
45
46     // For each source, verify that the playback state matches our expected playback state.
47     for (var k = 0; k < sources.length; ++k) {
48         var prefix = playbackStateName[sourceExpectedStates[k]] + sourceMessages[k];
49         if (sources[k].playbackState == sourceExpectedStates[k]) {
50             testPassed(prefix);
51         } else {
52             testFailed(prefix + ": Actual = " + playbackStateName[sources[k].playbackState]);
53             success = false;
54         }
55     }
56
57     // Figure out how many active sources there should be from the expected states.
58     var playingState = sources[0].PLAYING_STATE
59
60     var expectedActiveCount = 0;
61     for (k = 0; k < sourceExpectedStates.length; ++k) {
62         if (sourceExpectedStates[k] == playingState) {
63             ++expectedActiveCount;
64         }
65     }
66       
67     if (context.activeSourceCount == expectedActiveCount) {
68         testPassed(context.activeSourceCount + " are currently playing as expected.");
69     } else {
70         testFailed(context.activeSourceCount + " are currently playing, but expected " + expectedActiveCount + ".");
71         success = false;
72     }
73
74     if (success) {
75         testPassed("activeSourceCount and playbackState tests succeeded.");
76     } else {
77         testFailed("activeSourceCount and playbackState tests did not succeed.");
78     }
79
80     finishJSTest();
81 }
82
83 // sourceLength - length of source in seconds
84 // noteFunction - function to turn on source appropriately
85 // expectedState - expected state of the source at the end of rendering
86 // message - message to be displayed if test passes
87 function createTest(sourceLength, noteFunction, expectedState, message)
88 {
89     var s = context.createBufferSource();
90     s.buffer = createImpulseBuffer(context, timeToSampleFrame(sourceLength, sampleRate));
91     s.connect(context.destination);
92     noteFunction(s);
93     sources.push(s);
94     sourceMessages.push(message);
95     sourceExpectedStates.push(expectedState);
96 }
97
98 function runTest()
99 {
100     if (window.testRunner) {
101         testRunner.dumpAsText();
102         testRunner.waitUntilDone();
103     }
104
105     window.jsTestIsAsync = true;
106
107     // Create offline audio context, rendering for renderTime seconds.
108     context = new webkitAudioContext(2, timeToSampleFrame(renderTime, sampleRate), sampleRate);
109
110     // This is only used so we can access the playback state constants.
111     var bufferSource = context.createBufferSource();
112
113     // Dummy message so we know how long we're rendering so we can interpret the pass/fail messages
114     // correctly.
115     testPassed("Rendering time is " + renderTime + " seconds.");
116
117     // Test unscheduled state. Create 3 second source, but don't schedule it.
118
119     createTest(3,
120                function(s) { },
121                bufferSource.UNSCHEDULED_STATE,
122                "Source has been created");
123
124     // Test noteOn.
125
126     createTest(3,
127                function(s) { s.noteOn(renderTime + 1); },
128                bufferSource.SCHEDULED_STATE,
129                "3 second source scheduled to start at time " + (renderTime + 1));
130
131     createTest(2,
132                function(s) { s.noteOn(1); },
133                bufferSource.PLAYING_STATE,
134                "2 second source starting at time 1");
135       
136     createTest(1.25,
137                function(s) { s.noteOn(0); },
138                bufferSource.FINISHED_STATE,
139                "1.25 second source starting at time 0");
140
141     // Test noteGrainOn.
142
143     createTest(3,
144                function(s) { s.noteGrainOn(renderTime + 1, 0, 1); },
145                bufferSource.SCHEDULED_STATE,
146                "1 second grain scheduled to start at time " + (renderTime + 1));
147   
148     createTest(3,
149                function(s) { s.noteGrainOn(0.5, 0, 2); },
150                bufferSource.PLAYING_STATE,
151                "2 second grain starting at time 0.5");
152       
153     createTest(3,
154                function(s) { s.noteGrainOn(0.5, 0, 1); },
155                bufferSource.FINISHED_STATE,
156                "1 second grain starting at time 0.5");
157
158     // Test looping source
159
160     createTest(0.5,
161                function(s) { s.loop = true; s.noteOn(renderTime + 1); },
162                bufferSource.SCHEDULED_STATE,
163                "a looping 0.5 second source scheduled at time " + (renderTime + 1));
164
165     createTest(0.5,
166                function(s) { s.loop = true; s.noteOn(1.25); },
167                bufferSource.PLAYING_STATE,
168                "a looping 0.5 second source starting at time 1.25");
169
170     context.oncomplete = checkResult;
171     context.startRendering();
172 }
173       
174 runTest();
175 successfullyParsed = true;
176   
177 </script>
178
179 <script src="../fast/js/resources/js-test-post.js"></script>
180 </body>
181 </html>