OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 | |
3 <!-- | 2 <!-- |
4 Tests that we are able to schedule a series of notes to playback with sample-acc
uracy. | 3 Tests that we are able to schedule a series of notes to playback with sample-acc
uracy. |
5 We use an impulse so we can tell exactly where the rendering is happening. | 4 We use an impulse so we can tell exactly where the rendering is happening. |
6 --> | 5 --> |
| 6 <html> |
| 7 <head> |
| 8 <title> |
| 9 sample-accurate-scheduling.html |
| 10 </title> |
| 11 <script src="../../resources/testharness.js"></script> |
| 12 <script src="../../resources/testharnessreport.js"></script> |
| 13 <script src="../resources/audit-util.js"></script> |
| 14 <script src="../resources/audit.js"></script> |
| 15 <script src="../resources/buffer-loader.js"></script> |
| 16 </head> |
| 17 <body> |
| 18 <script id="layout-test-code"> |
| 19 let audit = Audit.createTaskRunner(); |
7 | 20 |
8 <html> | 21 let sampleRate = 44100.0; |
9 <head> | 22 let lengthInSeconds = 4; |
10 <script src="../../resources/testharness.js"></script> | |
11 <script src="../../resources/testharnessreport.js"></script> | |
12 <script src="../resources/audit-util.js"></script> | |
13 <script src="../resources/audit.js"></script> | |
14 <script src="../resources/buffer-loader.js"></script> | |
15 </head> | |
16 | 23 |
17 <body> | 24 let context = 0; |
| 25 let bufferLoader = 0; |
| 26 let impulse; |
18 | 27 |
19 <script> | 28 // See if we can render at exactly these sample offsets. |
20 let audit = Audit.createTaskRunner(); | 29 let sampleOffsets = [0, 3, 512, 517, 1000, 1005, 20000, 21234, 37590]; |
21 | 30 |
22 let sampleRate = 44100.0; | 31 function createImpulse() { |
23 let lengthInSeconds = 4; | 32 // An impulse has a value of 1 at time 0, and is otherwise 0. |
| 33 impulse = context.createBuffer(2, 512, sampleRate); |
| 34 let sampleDataL = impulse.getChannelData(0); |
| 35 let sampleDataR = impulse.getChannelData(1); |
| 36 sampleDataL[0] = 1.0; |
| 37 sampleDataR[0] = 1.0; |
| 38 } |
24 | 39 |
25 let context = 0; | 40 function playNote(time) { |
26 let bufferLoader = 0; | 41 let bufferSource = context.createBufferSource(); |
27 let impulse; | 42 bufferSource.buffer = impulse; |
| 43 bufferSource.connect(context.destination); |
| 44 bufferSource.start(time); |
| 45 } |
28 | 46 |
29 // See if we can render at exactly these sample offsets. | 47 function checkSampleAccuracy(buffer, should) { |
30 let sampleOffsets = [0, 3, 512, 517, 1000, 1005, 20000, 21234, 37590]; | 48 let bufferDataL = buffer.getChannelData(0); |
| 49 let bufferDataR = buffer.getChannelData(1); |
31 | 50 |
32 function createImpulse() { | 51 let impulseCount = 0; |
33 // An impulse has a value of 1 at time 0, and is otherwise 0. | 52 let badOffsetCount = 0; |
34 impulse = context.createBuffer(2, 512, sampleRate); | |
35 let sampleDataL = impulse.getChannelData(0); | |
36 let sampleDataR = impulse.getChannelData(1); | |
37 sampleDataL[0] = 1.0; | |
38 sampleDataR[0] = 1.0; | |
39 } | |
40 | 53 |
41 function playNote(time) { | 54 // Left and right channels must be the same. |
42 let bufferSource = context.createBufferSource(); | 55 should(bufferDataL, 'Content of left and right channels match and') |
43 bufferSource.buffer = impulse; | 56 .beEqualToArray(bufferDataR); |
44 bufferSource.connect(context.destination); | |
45 bufferSource.start(time); | |
46 } | |
47 | 57 |
48 function checkSampleAccuracy(buffer, should) { | 58 // Go through every sample and make sure it's 0, except at positions in |
49 let bufferDataL = buffer.getChannelData(0); | 59 // sampleOffsets. |
50 let bufferDataR = buffer.getChannelData(1); | 60 for (let i = 0; i < buffer.length; ++i) { |
51 | 61 if (bufferDataL[i] != 0) { |
52 let impulseCount = 0; | |
53 let badOffsetCount = 0; | |
54 | |
55 // Left and right channels must be the same. | |
56 should(bufferDataL, "Content of left and right channels match and") | |
57 .beEqualToArray(bufferDataR); | |
58 | |
59 // Go through every sample and make sure it's 0, except at positions in | |
60 // sampleOffsets. | |
61 for (let i = 0; i < buffer.length; ++i) { | |
62 if (bufferDataL[i] != 0) { | |
63 // Make sure this index is in sampleOffsets | 62 // Make sure this index is in sampleOffsets |
64 let found = false; | 63 let found = false; |
65 for (let j = 0; j < sampleOffsets.length; ++j) { | 64 for (let j = 0; j < sampleOffsets.length; ++j) { |
66 if (sampleOffsets[j] == i) { | 65 if (sampleOffsets[j] == i) { |
67 found = true; | 66 found = true; |
68 break; | 67 break; |
69 } | 68 } |
70 } | 69 } |
71 ++impulseCount; | 70 ++impulseCount; |
72 should(found, "Non-zero sample found at sample offset " + i) | 71 should(found, 'Non-zero sample found at sample offset ' + i) |
73 .beTrue(); | 72 .beTrue(); |
74 if (!found) { | 73 if (!found) { |
75 ++badOffsetCount; | 74 ++badOffsetCount; |
76 } | 75 } |
| 76 } |
77 } | 77 } |
78 } | |
79 | 78 |
80 should(impulseCount, "Number of impulses found") | 79 should(impulseCount, 'Number of impulses found') |
81 .beEqualTo(sampleOffsets.length); | 80 .beEqualTo(sampleOffsets.length); |
82 | 81 |
83 if (impulseCount == sampleOffsets.length) { | 82 if (impulseCount == sampleOffsets.length) { |
84 should(badOffsetCount, "bad offset") | 83 should(badOffsetCount, 'bad offset').beEqualTo(0); |
85 .beEqualTo(0); | 84 } |
86 } | 85 } |
87 } | |
88 | 86 |
89 audit.define({ | 87 audit.define( |
90 label: "test", | 88 {label: 'test', description: 'Test sample-accurate scheduling'}, |
91 description: "Test sample-accurate scheduling" | 89 function(task, should) { |
92 }, function (task, should) { | |
93 | 90 |
94 // Create offline audio context. | 91 // Create offline audio context. |
95 context = new OfflineAudioContext(2, sampleRate * lengthInSeconds, | 92 context = new OfflineAudioContext( |
96 sampleRate); | 93 2, sampleRate * lengthInSeconds, sampleRate); |
97 createImpulse(); | 94 createImpulse(); |
98 | 95 |
99 for (let i = 0; i < sampleOffsets.length; ++i) { | 96 for (let i = 0; i < sampleOffsets.length; ++i) { |
100 let timeInSeconds = sampleOffsets[i] / sampleRate; | 97 let timeInSeconds = sampleOffsets[i] / sampleRate; |
101 playNote(timeInSeconds); | 98 playNote(timeInSeconds); |
102 } | 99 } |
103 | |
104 context.startRendering() | |
105 .then(function (buffer) { | |
106 checkSampleAccuracy(buffer, should); | |
107 task.done(); | |
108 }); | |
109 }); | |
110 | 100 |
111 audit.run(); | 101 context.startRendering().then(function(buffer) { |
112 </script> | 102 checkSampleAccuracy(buffer, should); |
| 103 task.done(); |
| 104 }); |
| 105 }); |
113 | 106 |
114 </body> | 107 audit.run(); |
| 108 </script> |
| 109 </body> |
115 </html> | 110 </html> |
OLD | NEW |