Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 | 2 |
| 3 <!-- | 3 <!-- |
| 4 Tests that AudioBufferSourceNode supports loop-points with .loopStart and .loopE nd. | 4 Tests that AudioBufferSourceNode supports loop-points with .loopStart and .loopE nd. |
| 5 --> | 5 --> |
| 6 | 6 |
| 7 <html> | 7 <html> |
| 8 <head> | 8 <head> |
| 9 <script src="../../resources/testharness.js"></script> | |
| 10 <script src="../../resources/testharnessreport.js"></script> | |
| 9 <script src="../resources/audit-util.js"></script> | 11 <script src="../resources/audit-util.js"></script> |
| 10 <script src="../resources/audio-testing.js"></script> | 12 <script src="../resources/audit.js"></script> |
| 11 | 13 |
| 12 </head> | 14 </head> |
| 13 <body> | 15 <body> |
| 14 | 16 |
| 15 <script> | 17 <script> |
| 18 let audit = Audit.createTaskRunner(); | |
| 16 | 19 |
| 17 window.onload = init; | 20 let sampleRate = 44100.0; |
| 21 let numberOfNotes = 60; // play over a 5 octave range | |
| 22 let noteDuration = 0.025; | |
| 23 let noteSpacing = | |
| 24 noteDuration + 0.005; // leave 5ms of silence between each "note" | |
| 25 let lengthInSeconds = numberOfNotes * noteSpacing; | |
| 18 | 26 |
| 19 var sampleRate = 44100.0; | 27 let context = 0; |
| 20 var numberOfNotes = 60; // play over a 5 octave range | 28 let buffer = 0; |
| 21 var noteDuration = 0.025; | |
| 22 var noteSpacing = noteDuration + 0.005; // leave 5ms of silence between each "no te" | |
| 23 var lengthInSeconds = numberOfNotes * noteSpacing; | |
| 24 | |
| 25 var context = 0; | |
| 26 var buffer = 0; | |
| 27 | 29 |
| 28 function createTestBuffer(frequency, sampleRate) { | 30 function createTestBuffer(frequency, sampleRate) { |
| 29 // Create a buffer containing two periods at this frequency. | 31 // Create a buffer containing two periods at this frequency. |
| 30 // The 1st half is a pure sine wave period scaled by a linear ramp from 0 -> 1. | 32 // The 1st half is a pure sine wave period scaled by a linear ramp from 0 -> |
| 31 // The 2nd half of the buffer corresponds exactly to one pure sine wave peri od. | 33 // 1. The 2nd half of the buffer corresponds exactly to one pure sine wave |
| 32 var onePeriodDuration = 1 / frequency; | 34 // period. |
| 33 var sampleFrameLength = 2 * onePeriodDuration * sampleRate; | 35 let onePeriodDuration = 1 / frequency; |
| 36 let sampleFrameLength = 2 * onePeriodDuration * sampleRate; | |
| 34 | 37 |
| 35 var audioBuffer = context.createBuffer(1, sampleFrameLength, sampleRate); | 38 let audioBuffer = context.createBuffer(1, sampleFrameLength, sampleRate); |
| 36 | 39 |
| 37 var n = audioBuffer.length; | 40 let n = audioBuffer.length; |
| 38 var channelData = audioBuffer.getChannelData(0); | 41 let channelData = audioBuffer.getChannelData(0); |
| 39 | 42 |
| 40 for (var i = 0; i < n; ++i) { | 43 for (let i = 0; i < n; ++i) { |
| 41 var sample = Math.sin(frequency * 2.0*Math.PI * i / sampleRate); | 44 let sample = Math.sin(frequency * 2.0 * Math.PI * i / sampleRate); |
| 42 | 45 |
| 43 // Linear ramp from 0 -> 1 for the first period. | 46 // Linear ramp from 0 -> 1 for the first period. |
| 44 // Stay at 1 for the 2nd period. | 47 // Stay at 1 for the 2nd period. |
| 45 var scale = i < n / 2 ? i / (n / 2) : 1; | 48 let scale = i < n / 2 ? i / (n / 2) : 1; |
| 46 sample *= scale; | 49 sample *= scale; |
| 47 | 50 |
| 48 channelData[i] = sample; | 51 channelData[i] = sample; |
| 49 } | 52 } |
| 50 | 53 |
| 51 return audioBuffer; | 54 return audioBuffer; |
| 52 } | 55 } |
| 53 | 56 |
| 54 function playNote(time, duration, playbackRate) { | 57 function playNote(time, duration, playbackRate) { |
| 55 var source = context.createBufferSource(); | 58 let source = context.createBufferSource(); |
| 56 source.buffer = buffer; | 59 source.buffer = buffer; |
| 57 source.playbackRate.value = playbackRate; | 60 source.playbackRate.value = playbackRate; |
| 58 | 61 |
| 59 var gainNode = context.createGain(); | 62 let gainNode = context.createGain(); |
| 60 source.connect(gainNode); | 63 source.connect(gainNode); |
| 61 gainNode.connect(context.destination); | 64 gainNode.connect(context.destination); |
| 62 | 65 |
| 63 // Loop the 2nd half of the buffer. | 66 // Loop the 2nd half of the buffer. |
| 64 // We should be able to hear any problems as glitches if the looping incorre ctly indexes to | 67 // We should be able to hear any problems as glitches if the looping |
| 65 // anywhere outside of the desired loop-points, since only the 2nd half is a perfect sine-wave cycle, | 68 // incorrectly indexes to anywhere outside of the desired loop-points, since |
| 66 // while the 1st half of the buffer contains a linear ramp of a sine-wave cy cle. | 69 // only the 2nd half is a perfect sine-wave cycle, while the 1st half of the |
| 67 source.loop = true; | 70 // buffer contains a linear ramp of a sine-wave cycle. |
| 68 source.loopStart = 0.5 * buffer.duration; | 71 source.loop = true; |
| 69 source.loopEnd = buffer.duration; | 72 source.loopStart = 0.5 * buffer.duration; |
| 73 source.loopEnd = buffer.duration; | |
| 70 | 74 |
| 71 // Play for the given duration. | 75 // Play for the given duration. |
| 72 source.start(time); | 76 source.start(time); |
| 73 source.stop(time + duration); | 77 source.stop(time + duration); |
| 74 | 78 |
| 75 // Apply a quick linear fade-out to avoid a click at the end of the note. | 79 // Apply a quick linear fade-out to avoid a click at the end of the note. |
| 76 gainNode.gain.value = 1; | 80 gainNode.gain.value = 1; |
| 77 gainNode.gain.setValueAtTime(1, time + duration - 0.005); | 81 gainNode.gain.setValueAtTime(1, time + duration - 0.005); |
| 78 gainNode.gain.linearRampToValueAtTime(0, time + duration); | 82 gainNode.gain.linearRampToValueAtTime(0, time + duration); |
| 79 } | 83 } |
| 80 | 84 |
| 81 function init() { | 85 audit.define('test', (task, should) => { |
| 82 if (!window.testRunner) | 86 should(window.testRunner, 'window.testRunner').notBeEqualTo(undefined); |
| 83 return; | |
| 84 | 87 |
| 85 // Create offline audio context. | 88 // Create offline audio context. |
| 86 context = new OfflineAudioContext(2, sampleRate * lengthInSeconds, sampleRat e); | 89 context = |
| 90 new OfflineAudioContext(2, sampleRate * lengthInSeconds, sampleRate); | |
| 87 | 91 |
| 88 // Create the test buffer. | 92 // Create the test buffer. |
| 89 // We'll loop this with the loop-points set for the 2nd half of this buffer. | 93 // We'll loop this with the loop-points set for the 2nd half of this buffer. |
| 90 buffer = createTestBuffer(440.0, sampleRate); | 94 buffer = createTestBuffer(440.0, sampleRate); |
| 91 | 95 |
| 92 // Play all the notes as a chromatic scale. | 96 // Play all the notes as a chromatic scale. |
| 93 for (var i = 0; i < numberOfNotes; ++i) { | 97 for (let i = 0; i < numberOfNotes; ++i) { |
| 94 var time = i * noteSpacing; | 98 let time = i * noteSpacing; |
| 95 var semitone = i - numberOfNotes/2; // start three octaves down | 99 let semitone = i - numberOfNotes / 2; // start three octaves down |
|
hongchan
2017/02/27 18:05:34
This comment can be between l.98 and l.99.
| |
| 96 | 100 |
| 97 // Convert from semitone to rate. | 101 // Convert from semitone to rate. |
| 98 var playbackRate = Math.pow(2, semitone / 12); | 102 let playbackRate = Math.pow(2, semitone / 12); |
| 99 | 103 |
| 100 playNote(time, noteDuration, playbackRate); | 104 playNote(time, noteDuration, playbackRate); |
| 101 } | 105 } |
| 102 | 106 |
| 103 context.oncomplete = finishAudioTest; | 107 context.oncomplete = (event) => { |
|
hongchan
2017/02/27 18:05:34
Can we use promise?
Raymond Toy
2017/02/27 18:13:23
Yes, I think we can, but we need to keep some test
hongchan
2017/02/27 18:19:22
If we want to test that, that should be in the OAC
| |
| 104 context.startRendering(); | 108 finishAudioTest(event); |
| 109 task.done(); | |
| 110 }; | |
| 105 | 111 |
| 106 testRunner.waitUntilDone(); | 112 context.startRendering(); |
| 107 } | 113 testRunner.waitUntilDone(); |
| 114 }); | |
| 115 | |
| 116 audit.run(); | |
| 108 | 117 |
| 109 </script> | 118 </script> |
| 110 | 119 |
| 111 </body> | 120 </body> |
| 112 </html> | 121 </html> |
| OLD | NEW |