OLD | NEW |
| (Empty) |
1 <!doctype html> | |
2 <html> | |
3 <head> | |
4 <title>Test ConstantSourceNode Output</title> | |
5 <script src="../resources/testharness.js"></script> | |
6 <script src="../resources/testharnessreport.js"></script> | |
7 <script src="resources/audit-util.js"></script> | |
8 <script src="resources/audio-testing.js"></script> | |
9 <script src="resources/audioparam-testing.js"></script> | |
10 </head> | |
11 | |
12 <body> | |
13 <script> | |
14 var sampleRate = 48000; | |
15 var renderDuration = 0.125; | |
16 var renderFrames = sampleRate * renderDuration; | |
17 | |
18 var audit = Audit.createTaskRunner(); | |
19 | |
20 audit.defineTask("constant source", function (taskDone) { | |
21 // Verify a constant source outputs the correct (fixed) constant. | |
22 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
23 var node = new ConstantSourceNode(context, { | |
24 offset: 0.5 | |
25 }); | |
26 node.connect(context.destination); | |
27 node.start(); | |
28 | |
29 context.startRendering().then(function (buffer) { | |
30 var actual = buffer.getChannelData(0); | |
31 var expected = new Float32Array(actual.length); | |
32 expected.fill(node.offset.value); | |
33 | |
34 Should("ConstantSourceNode({offset: 0.5})", actual) | |
35 .beEqualToArray(expected); | |
36 }).then(taskDone); | |
37 }); | |
38 | |
39 audit.defineTask("start/stop", function (taskDone) { | |
40 // Verify a constant source starts and stops at the correct time and has | |
41 // the correct (fixed) value. | |
42 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
43 var node = new ConstantSourceNode(context, { | |
44 offset: 1 | |
45 }); | |
46 node.connect(context.destination); | |
47 | |
48 var startFrame = 10; | |
49 var stopFrame = 300; | |
50 | |
51 node.start(startFrame / context.sampleRate); | |
52 node.stop(stopFrame / context.sampleRate); | |
53 | |
54 context.startRendering().then(function (buffer) { | |
55 var actual = buffer.getChannelData(0); | |
56 var expected = new Float32Array(actual.length); | |
57 // The expected output is all 1s from start to stop time. | |
58 expected.fill(0); | |
59 | |
60 for (var k = startFrame; k < stopFrame; ++k) { | |
61 expected[k] = node.offset.value; | |
62 } | |
63 | |
64 var success = Should("ConstantSourceNode frames [0, " + | |
65 startFrame + ")", | |
66 actual.slice(0, startFrame)) | |
67 .beConstantValueOf(0); | |
68 | |
69 success = Should("ConstantSourceNode frames [" + startFrame + | |
70 ", " + | |
71 stopFrame + ")", | |
72 actual.slice(startFrame, stopFrame)) | |
73 .beConstantValueOf(1) && success; | |
74 | |
75 success = Should("ConstantSourceNode frames [" + stopFrame + ", " + | |
76 renderFrames + ")", | |
77 actual.slice(stopFrame)) | |
78 .beConstantValueOf(0) && success; | |
79 | |
80 Should("ConstantSourceNode started and stopped", success) | |
81 .summarize( | |
82 "at the correct times with the correct values", | |
83 "with the incorrect times or values"); | |
84 }).then(taskDone); | |
85 | |
86 }); | |
87 | |
88 audit.defineTask("basic automation", function (taskDone) { | |
89 // Verify that automation works as expected. | |
90 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
91 var source = context.createConstantSource(); | |
92 source.connect(context.destination); | |
93 | |
94 var rampEndTime = renderDuration / 2; | |
95 source.offset.setValueAtTime(0.5, 0); | |
96 source.offset.linearRampToValueAtTime(1, rampEndTime); | |
97 | |
98 source.start(); | |
99 | |
100 context.startRendering() | |
101 .then(function (buffer) { | |
102 var actual = buffer.getChannelData(0); | |
103 var expected = createLinearRampArray(0, rampEndTime, 0.5, 1, | |
104 context.sampleRate); | |
105 | |
106 var rampEndFrame = Math.ceil(rampEndTime * context.sampleRate); | |
107 var success = Should("ConstantSourceNode.linearRamp(1, 0.5)", | |
108 actual.slice(0, rampEndFrame)) | |
109 .beCloseToArray(expected, { | |
110 // Experimentally determined threshold.. | |
111 relativeThreshold: 7.1610e-7 | |
112 }); | |
113 | |
114 success = Should("ConstantSourceNode after ramp", | |
115 actual.slice(rampEndFrame)) | |
116 .beConstantValueOf(1) && success; | |
117 | |
118 Should("ConstantSourceNode automation", success) | |
119 .summarize( | |
120 "produced the correct values", | |
121 "did not produce the correct values"); | |
122 }) | |
123 .then(taskDone); | |
124 }); | |
125 | |
126 audit.defineTask("connected audioparam", function (taskDone) { | |
127 // Verify the constant source output with connected AudioParam produces | |
128 // the correct output. | |
129 var context = new OfflineAudioContext(2, renderFrames, sampleRate) | |
130 context.destination.channelInterpretation = "discrete"; | |
131 var source = new ConstantSourceNode(context, { | |
132 offset: 1 | |
133 }); | |
134 var osc = context.createOscillator(); | |
135 var merger = context.createChannelMerger(2); | |
136 merger.connect(context.destination); | |
137 | |
138 source.connect(merger, 0, 0); | |
139 osc.connect(merger, 0, 1); | |
140 osc.connect(source.offset); | |
141 | |
142 osc.start(); | |
143 var sourceStartFrame = 10; | |
144 source.start(sourceStartFrame / context.sampleRate); | |
145 | |
146 context.startRendering() | |
147 .then(function (buffer) { | |
148 // Channel 0 and 1 should be identical, except channel 0 (the | |
149 // source) is silent at the beginning. | |
150 var actual = buffer.getChannelData(0); | |
151 var expected = buffer.getChannelData(1); | |
152 // The expected output should be oscillator + 1 because offset | |
153 // is 1. | |
154 expected = expected.map(x => 1 + x); | |
155 var success = true; | |
156 | |
157 // The initial part of the output should be silent because the | |
158 // source node hasn't started yet. | |
159 success = Should("ConstantSourceNode frames [0, " + | |
160 sourceStartFrame + ")", actual.slice(0, sourceStartFrame) | |
161 ) | |
162 .beConstantValueOf(0); | |
163 // The rest of the output should be the same as the oscillator (in | |
164 // channel 1) | |
165 success = Should("ConstantSourceNode frames [" + | |
166 sourceStartFrame + ", " + renderFrames + ")", | |
167 actual.slice(sourceStartFrame)) | |
168 .beCloseToArray(expected.slice(sourceStartFrame), 0); | |
169 | |
170 Should("ConstantSourceNode with connected AudioParam", | |
171 success) | |
172 .summarize( | |
173 "had the expected output", | |
174 "did not have the expected output"); | |
175 }) | |
176 .then(taskDone); | |
177 }); | |
178 | |
179 audit.runTasks(); | |
180 </script> | |
181 </body> | |
182 </html> | |
OLD | NEW |