Index: third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html |
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html |
index 8e3a8232c2d17cebf0d98d359f6d6ed7b8a51353..2c23649aeda6210c720906726e38e9e59b8eac09 100644 |
--- a/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html |
+++ b/third_party/WebKit/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-points.html |
@@ -1,156 +1,160 @@ |
<!DOCTYPE html> |
- |
<!-- |
Tests that AudioBufferSourceNode supports loop-points with .loopStart and .loopEnd. |
--> |
- |
<html> |
-<head> |
-<script src="../../resources/testharness.js"></script> |
-<script src="../../resources/testharnessreport.js"></script> |
-<script src="../resources/audit-util.js"></script> |
-<script src="../resources/audit.js"></script> |
- |
-</head> |
-<body> |
- |
-<script> |
-let audit = Audit.createTaskRunner(); |
- |
-let sampleRate = 44100.0; |
-let numberOfNotes = 60; // play over a 5 octave range |
-let noteDuration = 0.025; |
-let noteSpacing = |
- noteDuration + 0.005; // leave 5ms of silence between each "note" |
-let lengthInSeconds = numberOfNotes * noteSpacing; |
- |
-let context = 0; |
-let expectedAudio; |
- |
-function createTestBuffer(frequency, sampleRate) { |
- // Create a buffer containing two periods at this frequency. |
- // The 1st half is a pure sine wave period scaled by a linear ramp from 0 -> |
- // 1. The 2nd half of the buffer corresponds exactly to one pure sine wave |
- // period. |
- let onePeriodDuration = 1 / frequency; |
- let sampleFrameLength = 2 * onePeriodDuration * sampleRate; |
- |
- let audioBuffer = context.createBuffer(1, sampleFrameLength, sampleRate); |
- |
- let n = audioBuffer.length; |
- let channelData = audioBuffer.getChannelData(0); |
- |
- for (let i = 0; i < n; ++i) { |
- let sample = Math.sin(frequency * 2.0 * Math.PI * i / sampleRate); |
- |
- // Linear ramp from 0 -> 1 for the first period. |
- // Stay at 1 for the 2nd period. |
- let scale = i < n / 2 ? i / (n / 2) : 1; |
- sample *= scale; |
- |
- channelData[i] = sample; |
- } |
- |
- return audioBuffer; |
-} |
- |
-function playNote(buffer, time, duration, playbackRate) { |
- let source = context.createBufferSource(); |
- source.buffer = buffer; |
- source.playbackRate.value = playbackRate; |
- |
- let gainNode = context.createGain(); |
- source.connect(gainNode); |
- gainNode.connect(context.destination); |
- |
- // Loop the 2nd half of the buffer. |
- // We should be able to hear any problems as glitches if the looping |
- // incorrectly indexes to anywhere outside of the desired loop-points, since |
- // only the 2nd half is a perfect sine-wave cycle, while the 1st half of the |
- // buffer contains a linear ramp of a sine-wave cycle. |
- source.loop = true; |
- source.loopStart = 0.5 * buffer.duration; |
- source.loopEnd = buffer.duration; |
- |
- // Play for the given duration. |
- source.start(time); |
- source.stop(time + duration); |
- |
- // Apply a quick linear fade-out to avoid a click at the end of the note. |
- gainNode.gain.value = 1; |
- gainNode.gain.setValueAtTime(1, time + duration - 0.005); |
- gainNode.gain.linearRampToValueAtTime(0, time + duration); |
-} |
- |
-audit.define( |
- {label: 'initialize', description: 'Set up context and expected results'}, |
- (task, should) => { |
- // Create offline audio context. |
- should( |
- () => {context = new OfflineAudioContext( |
- 2, sampleRate * lengthInSeconds, sampleRate)}, |
- 'Creating context for testing') |
- .notThrow(); |
- |
- should( |
- Audit.loadFileFromUrl('audiobuffersource-loop-points-expected.wav') |
- .then(arrayBuffer => { |
- context.decodeAudioData(arrayBuffer).then(audioBuffer => { |
- expectedAudio = audioBuffer; |
- }); |
- }), |
- 'Fetching expected audio') |
- .beResolved() |
- .then(() => task.done()); |
- }); |
- |
-audit.define( |
- { |
- label: 'test', |
- description: 'Test loop points and compare with expected results' |
- }, |
- (task, should) => { |
- // Create the test buffer. |
- // We'll loop this with the loop-points set for the 2nd half of this |
- // buffer. |
- let buffer = createTestBuffer(440.0, sampleRate); |
- |
- // Play all the notes as a chromatic scale. |
- for (let i = 0; i < numberOfNotes; ++i) { |
- let time = i * noteSpacing; |
- // start three octaves down |
- let semitone = i - numberOfNotes / 2; |
- |
- // Convert from semitone to rate. |
- let playbackRate = Math.pow(2, semitone / 12); |
- |
- playNote(buffer, time, noteDuration, playbackRate); |
+ <head> |
+ <title> |
+ audiobuffersource-loop-points.html |
+ </title> |
+ <script src="../../resources/testharness.js"></script> |
+ <script src="../../resources/testharnessreport.js"></script> |
+ <script src="../resources/audit-util.js"></script> |
+ <script src="../resources/audit.js"></script> |
+ </head> |
+ <body> |
+ <script id="layout-test-code"> |
+ let audit = Audit.createTaskRunner(); |
+ |
+ let sampleRate = 44100.0; |
+ let numberOfNotes = 60; // play over a 5 octave range |
+ let noteDuration = 0.025; |
+ let noteSpacing = |
+ noteDuration + 0.005; // leave 5ms of silence between each "note" |
+ let lengthInSeconds = numberOfNotes * noteSpacing; |
+ |
+ let context = 0; |
+ let expectedAudio; |
+ |
+ function createTestBuffer(frequency, sampleRate) { |
+ // Create a buffer containing two periods at this frequency. |
+ // The 1st half is a pure sine wave period scaled by a linear ramp from |
+ // 0 -> 1. The 2nd half of the buffer corresponds exactly to one pure |
+ // sine wave period. |
+ let onePeriodDuration = 1 / frequency; |
+ let sampleFrameLength = 2 * onePeriodDuration * sampleRate; |
+ |
+ let audioBuffer = |
+ context.createBuffer(1, sampleFrameLength, sampleRate); |
+ |
+ let n = audioBuffer.length; |
+ let channelData = audioBuffer.getChannelData(0); |
+ |
+ for (let i = 0; i < n; ++i) { |
+ let sample = Math.sin(frequency * 2.0 * Math.PI * i / sampleRate); |
+ |
+ // Linear ramp from 0 -> 1 for the first period. |
+ // Stay at 1 for the 2nd period. |
+ let scale = i < n / 2 ? i / (n / 2) : 1; |
+ sample *= scale; |
+ |
+ channelData[i] = sample; |
+ } |
+ |
+ return audioBuffer; |
} |
- context.startRendering() |
- .then(renderedAudio => { |
- // Compute a threshold based on the maximum error, |maxUlp|, in ULP. |
- // This is experimentally determined. Assuming that the reference |
- // file is a 16-bit wav file, the max values in the wave file |
- // are +/- 32768. |
- let maxUlp = 0.9999; |
- let threshold = maxUlp / 32768; |
- |
- for (let k = 0; k < renderedAudio.numberOfChannels; ++k) { |
- should( |
- renderedAudio.getChannelData(k), |
- 'Rendered audio for channel ' + k) |
- .beCloseToArray( |
- expectedAudio.getChannelData(k), |
- {absoluteThreshold: threshold}); |
- } |
- }) |
- .then(() => task.done()); |
- }); |
- |
-audit.run(); |
+ function playNote(buffer, time, duration, playbackRate) { |
+ let source = context.createBufferSource(); |
+ source.buffer = buffer; |
+ source.playbackRate.value = playbackRate; |
+ |
+ let gainNode = context.createGain(); |
+ source.connect(gainNode); |
+ gainNode.connect(context.destination); |
+ |
+ // Loop the 2nd half of the buffer. |
+ // We should be able to hear any problems as glitches if the looping |
+ // incorrectly indexes to anywhere outside of the desired loop-points, |
+ // since only the 2nd half is a perfect sine-wave cycle, while the 1st |
+ // half of the buffer contains a linear ramp of a sine-wave cycle. |
+ source.loop = true; |
+ source.loopStart = 0.5 * buffer.duration; |
+ source.loopEnd = buffer.duration; |
+ |
+ // Play for the given duration. |
+ source.start(time); |
+ source.stop(time + duration); |
+ |
+ // Apply a quick linear fade-out to avoid a click at the end of the |
+ // note. |
+ gainNode.gain.value = 1; |
+ gainNode.gain.setValueAtTime(1, time + duration - 0.005); |
+ gainNode.gain.linearRampToValueAtTime(0, time + duration); |
+ } |
-</script> |
+ audit.define( |
+ { |
+ label: 'initialize', |
+ description: 'Set up context and expected results' |
+ }, |
+ (task, should) => { |
+ // Create offline audio context. |
+ should( |
+ () => {context = new OfflineAudioContext( |
+ 2, sampleRate * lengthInSeconds, sampleRate)}, |
+ 'Creating context for testing') |
+ .notThrow(); |
+ |
+ should( |
+ Audit |
+ .loadFileFromUrl( |
+ 'audiobuffersource-loop-points-expected.wav') |
+ .then(arrayBuffer => { |
+ context.decodeAudioData(arrayBuffer).then(audioBuffer => { |
+ expectedAudio = audioBuffer; |
+ }); |
+ }), |
+ 'Fetching expected audio') |
+ .beResolved() |
+ .then(() => task.done()); |
+ }); |
+ |
+ audit.define( |
+ { |
+ label: 'test', |
+ description: 'Test loop points and compare with expected results' |
+ }, |
+ (task, should) => { |
+ // Create the test buffer. |
+ // We'll loop this with the loop-points set for the 2nd half of this |
+ // buffer. |
+ let buffer = createTestBuffer(440.0, sampleRate); |
+ |
+ // Play all the notes as a chromatic scale. |
+ for (let i = 0; i < numberOfNotes; ++i) { |
+ let time = i * noteSpacing; |
+ // start three octaves down |
+ let semitone = i - numberOfNotes / 2; |
+ |
+ // Convert from semitone to rate. |
+ let playbackRate = Math.pow(2, semitone / 12); |
+ |
+ playNote(buffer, time, noteDuration, playbackRate); |
+ } |
-</body> |
+ context.startRendering() |
+ .then(renderedAudio => { |
+ // Compute a threshold based on the maximum error, |maxUlp|, |
+ // in ULP. This is experimentally determined. Assuming that |
+ // the reference file is a 16-bit wav file, the max values in |
+ // the wave file are +/- 32768. |
+ let maxUlp = 0.9999; |
+ let threshold = maxUlp / 32768; |
+ |
+ for (let k = 0; k < renderedAudio.numberOfChannels; ++k) { |
+ should( |
+ renderedAudio.getChannelData(k), |
+ 'Rendered audio for channel ' + k) |
+ .beCloseToArray( |
+ expectedAudio.getChannelData(k), |
+ {absoluteThreshold: threshold}); |
+ } |
+ }) |
+ .then(() => task.done()); |
+ }); |
+ |
+ audit.run(); |
+ </script> |
+ </body> |
</html> |