4 <script src=
"../resources/js-test.js"></script>
5 <script src=
"resources/compatibility.js"></script>
6 <script src=
"resources/audio-testing.js"></script>
7 <title>Test Basic Functionality of AudioBuffer.copyFromChannel and AudioBuffer.copyToChannel
</title>
12 description("Test Basic Functionality of copyFromChannel and AudioBuffer.copyToChannel");
14 window
.jsTestIsAsync
= true;
16 // Define utility routines.
18 // Initialize the AudioBuffer |buffer| with a ramp signal on each channel. The ramp starts at
19 // channel number + 1.
20 function initializeAudioBufferRamp (buffer
) {
21 for (var c
= 0; c
< buffer
.numberOfChannels
; ++c
) {
22 var d
= buffer
.getChannelData(c
);
23 for (var k
= 0; k
< d
.length
; ++k
) {
29 // Create a Float32Array of length |length| and initialize the array to -1.
30 function createInitializedF32Array(length
) {
31 var x
= new Float32Array(length
);
32 for (var k
= 0; k
< length
; ++k
) {
38 // Create a Float32Array of length |length| that is initialized to be a ramp starting at 1.
39 function createFloat32RampArray(length
) {
40 var x
= new Float32Array(length
);
41 for (var k
= 0; k
< x
.length
; ++k
) {
48 // Test that the array |x| is a ramp starting at value |start| of length |length|, starting at
49 // |startIndex| in the array. |startIndex| is optional and defaults to 0. Any other values
51 function shouldBeRamp(testName
, x
, startValue
, length
, startIndex
) {
53 var startingIndex
= startIndex
|| 0;
54 var expected
= Array(x
.length
);
56 // Fill the expected array with the correct results.
58 // The initial part (if any) must be -1.
59 for (k
= 0; k
< startingIndex
; ++k
) {
63 // The second part should be a ramp starting with |startValue|
64 for (; k
< startingIndex
+ length
; ++k
) {
65 expected
[k
] = startValue
+ k
- startingIndex
;
68 // The last part (if any) should be -1.
69 for (; k
< x
.length
; ++k
) {
73 Should(testName
, x
, {numberOfArrayLog
: 32}).beEqualToArray(expected
);
76 var audit
= Audit
.createTaskRunner();
78 var context
= new AudioContext();
79 // Temp array for testing exceptions for copyToChannel/copyFromChannel. The length is arbitrary.
80 var x
= new Float32Array(8);
82 // Number of frames in the AudioBuffer for testing. This is pretty arbitrary so choose a
83 // fairly small value.
84 var bufferLength
= 16;
86 // Number of channels in the AudioBuffer. Also arbitrary, but it should be greater than 1 for
88 var numberOfChannels
= 3;
90 // AudioBuffer that will be used for testing copyFrom and copyTo.
91 var buffer
= context
.createBuffer(numberOfChannels
, bufferLength
, context
.sampleRate
);
93 var initialValues
= Array(numberOfChannels
);
96 audit
.defineTask("initialize", function (done
) {
98 for (var k
= 0; k
< numberOfChannels
; ++k
) {
99 initialValues
[k
] = -1;
105 // Test that expected exceptions are signaled for copyFrom.
106 audit
.defineTask("copyFrom-exceptions", function (done
) {
107 shouldBeDefined("AudioBuffer.prototype.copyFromChannel");
109 Should("buffer = context.createBuffer(" + numberOfChannels
+ ", " + bufferLength
+ ", context.sampleRate)",
111 buffer
= context
.createBuffer(numberOfChannels
, bufferLength
, context
.sampleRate
);
113 Should("buffer.copyFromChannel(null, 0)", function () {
114 buffer
.copyFromChannel(null, 0);
115 }).throw("TypeMismatchError");
116 Should("buffer.copyFromChannel(context, 0)", function () {
117 buffer
.copyFromChannel(context
, 0);
118 }).throw("TypeMismatchError");
119 Should("buffer.copyFromChannel(x, -1)", function () {
120 buffer
.copyFromChannel(x
, -1);
121 }).throw("IndexSizeError");
122 Should("buffer.copyFromChannel(x, " + numberOfChannels
+ ")", function () {
123 buffer
.copyFromChannel(x
, numberOfChannels
);
124 }).throw("IndexSizeError");;
125 Should("buffer.copyFromChannel(x, 0, -1)", function () {
126 buffer
.copyFromChannel(x
, 0, -1);
127 }).throw("IndexSizeError");
128 Should("buffer.copyFromChannel(x, 0, " + bufferLength
+ ")", function () {
129 buffer
.copyFromChannel(x
, 0, bufferLength
);
130 }).throw("IndexSizeError");
132 shouldThrow("buffer.copyFromChannel(x, 3)");
137 // Test that expected exceptions are signaled for copyTo.
138 audit
.defineTask("copyTo-exceptions", function (done
) {
139 shouldBeDefined("AudioBuffer.prototype.copyToChannel");
140 Should("buffer.copyToChannel(null, 0)", function () {
141 buffer
.copyToChannel(null, 0);
142 }).throw("TypeMismatchError");
143 Should("buffer.copyToChannel(context, 0)", function () {
144 buffer
.copyToChannel(context
, 0);
145 }).throw("TypeMismatchError");
146 Should("buffer.copyToChannel(x, -1)", function () {
147 buffer
.copyToChannel(x
, -1);
148 }).throw("IndexSizeError");
149 Should("buffer.copyToChannel(x, " + numberOfChannels
+ ")", function () {
150 buffer
.copyToChannel(x
, numberOfChannels
);
151 }).throw("IndexSizeError");
152 Should("buffer.copyToChannel(x, 0, -1)", function () {
153 buffer
.copyToChannel(x
, 0, -1);
154 }).throw("IndexSizeError");
155 Should("buffer.copyToChannel(x, 0, " + bufferLength
+ ")", function () {
156 buffer
.copyToChannel(x
, 0, bufferLength
);
157 }).throw("IndexSizeError");
159 shouldThrow("buffer.copyToChannel(x, 3)");
164 // Test copyFromChannel
165 audit
.defineTask("copyFrom-validate", function (done
) {
166 // Initialize the AudioBuffer to a ramp for testing copyFrom.
167 initializeAudioBufferRamp(buffer
);
169 // Test copyFrom operation with a short destination array, filling the destination completely.
170 for (var c
= 0; c
< numberOfChannels
; ++c
) {
171 var dst8
= createInitializedF32Array(8);
172 buffer
.copyFromChannel(dst8
, c
);
173 shouldBeRamp("buffer.copyFromChannel(dst8, " + c
+ ")", dst8
, c
+ 1, 8)
176 // Test copyFrom operation with a short destination array using a non-zero start index that
177 // still fills the destination completely.
178 for (var c
= 0; c
< numberOfChannels
; ++c
) {
179 var dst8
= createInitializedF32Array(8);
180 buffer
.copyFromChannel(dst8
, c
, 1);
181 shouldBeRamp("buffer.copyFromChannel(dst8, " + c
+ ", 1)", dst8
, c
+ 2, 8)
184 // Test copyFrom operation with a short destination array using a non-zero start index that
185 // does not fill the destinatiom completely. The extra elements should be unchanged.
186 for (var c
= 0; c
< numberOfChannels
; ++c
) {
187 var dst8
= createInitializedF32Array(8);
188 var startInChannel
= bufferLength
- 5;
189 buffer
.copyFromChannel(dst8
, c
, startInChannel
);
190 shouldBeRamp("buffer.copyFromChannel(dst8, " + c
+ ", " + startInChannel
+ ")", dst8
,
191 c
+ 1 + startInChannel
, bufferLength
- startInChannel
);
194 // Copy operation with the destination longer than the buffer, leaving the trailing elements
195 // of the destination untouched.
196 for (var c
= 0; c
< numberOfChannels
; ++c
) {
197 var dst26
= createInitializedF32Array(bufferLength
+ 10);
198 buffer
.copyFromChannel(dst26
, c
);
199 shouldBeRamp("buffer.copyFromChannel(dst26, " + c
+ ")", dst26
,
200 c
+ 1, bufferLength
);
207 audit
.defineTask("copyTo-validate", function (done
) {
208 // Create a source consisting of a ramp starting at 1, longer than the AudioBuffer
209 var src
= createFloat32RampArray(bufferLength
+ 10);
211 // Test copyTo with AudioBuffer shorter than Float32Array. The AudioBuffer should be
212 // completely filled with the Float32Array.
213 Should("buffer = createConstantBuffer(context, " + bufferLength
+ ", [" + initialValues
+ "])",
215 buffer
= createConstantBuffer(context
, bufferLength
, initialValues
);
218 for (var c
= 0; c
< numberOfChannels
; ++c
) {
219 buffer
.copyToChannel(src
, c
);
220 shouldBeRamp("buffer.copyToChannel(src, " + c
+ ")", buffer
.getChannelData(c
), 1, bufferLength
);
223 // Test copyTo with AudioBuffer longer than the Float32Array. The tail of the AudioBuffer
224 // should be unchanged.
225 buffer
= createConstantBuffer(context
, bufferLength
, initialValues
);
226 var src10
= createFloat32RampArray(10);
227 for (var c
= 0; c
< numberOfChannels
; ++c
) {
228 buffer
.copyToChannel(src10
, c
);
229 shouldBeRamp("buffer.copyToChannel(src10, " + c
+ ")", buffer
.getChannelData(c
), 1, 10);
232 // Test copyTo with non-default startInChannel. Part of the AudioBuffer should filled with
233 // the beginning and end sections untouched.
234 buffer
= createConstantBuffer(context
, bufferLength
, initialValues
);
235 for (var c
= 0; c
< numberOfChannels
; ++c
) {
236 var startInChannel
= 5;
237 buffer
.copyToChannel(src10
, c
, startInChannel
);
239 shouldBeRamp("buffer.copyToChannel(src10, " + c
+ ", " + startInChannel
+ ")",
240 buffer
.getChannelData(c
), 1, src10
.length
, startInChannel
);
246 audit
.defineTask("finish", function (done
) {
253 "copyFrom-exceptions",
260 successfullyParsed
= true;