Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>AudioBufferSourceNode - playbackRate test</title> | 4 <title>AudioBufferSourceNode - playbackRate test</title> |
| 5 <script src="../../resources/js-test.js"></script> | 5 <script src="../../resources/testharness.js"></script> |
| 6 <script src="../../resources/testharnessreport.js"></script> | |
| 6 <script src="../resources/audit-util.js"></script> | 7 <script src="../resources/audit-util.js"></script> |
| 7 <script src="../resources/audio-testing.js"></script> | 8 <script src="../resources/audio-testing.js"></script> |
| 8 </head> | 9 </head> |
| 9 <body> | 10 <body> |
| 10 <script> | 11 <script> |
| 11 description("Test if AudioBufferSourceNode.playbackRate can playback at differ ent rates properly."); | 12 let audit = Audit.createTaskRunner(); |
| 12 window.jsTestIsAsync = true; | |
| 13 | 13 |
| 14 // Any sample rate mutiple of 128 is valid for this test, but here it uses | 14 // Any sample rate mutiple of 128 is valid for this test, but here it uses |
| 15 // 48000Hz because it is a commonly used number that happens to be multiple | 15 // 48000Hz because it is a commonly used number that happens to be multiple |
| 16 // of 128. | 16 // of 128. |
| 17 var sampleRate = 48000; | 17 let sampleRate = 48000; |
| 18 | 18 |
| 19 // The test iterates over 60 pitches starting from 36. (MIDI pitch of C2) | 19 // The test iterates over 60 pitches starting from 36. (MIDI pitch of C2) |
| 20 var fundamentalPitch = 36; | 20 let fundamentalPitch = 36; |
| 21 var numberOfPitches = 60; | 21 let numberOfPitches = 60; |
| 22 | 22 |
| 23 var noteDuration = 0.025; | 23 let noteDuration = 0.025; |
| 24 var totalDuration = noteDuration * numberOfPitches; | 24 let totalDuration = noteDuration * numberOfPitches; |
| 25 | 25 |
| 26 // Test constraints for each octave. | 26 // Test constraints for each octave. |
| 27 var testConstraints = [{ | 27 let testConstraints = [{ |
| 28 thresholdSNR: 103.8508, | 28 thresholdSNR: 103.8508, |
| 29 thresholdDiffULP: 0.3028 | 29 thresholdDiffULP: 0.3028 |
| 30 }, { | 30 }, { |
| 31 thresholdSNR: 103.8657, | 31 thresholdSNR: 103.8657, |
| 32 thresholdDiffULP: 0.3029 | 32 thresholdDiffULP: 0.3029 |
| 33 }, { | 33 }, { |
| 34 thresholdSNR: 103.8141, | 34 thresholdSNR: 103.8141, |
| 35 thresholdDiffULP: 0.3047 | 35 thresholdDiffULP: 0.3047 |
| 36 }, { | 36 }, { |
| 37 thresholdSNR: 103.6818, | 37 thresholdSNR: 103.6818, |
| 38 thresholdDiffULP: 0.3262 | 38 thresholdDiffULP: 0.3262 |
| 39 }, { | 39 }, { |
| 40 thresholdSNR: 103.1514, | 40 thresholdSNR: 103.1514, |
| 41 thresholdDiffULP: 0.3946 | 41 thresholdDiffULP: 0.3946 |
| 42 }]; | 42 }]; |
| 43 | 43 |
| 44 function pitchToFrequency(midiPitch) { | 44 function pitchToFrequency(midiPitch) { |
| 45 return 440 * Math.pow(2, (Math.floor(midiPitch) - 69) / 12); | 45 return 440 * Math.pow(2, (Math.floor(midiPitch) - 69) / 12); |
| 46 } | 46 } |
| 47 | 47 |
| 48 function pitchDiffToPlaybackRate(midiPitchDiff) { | 48 function pitchDiffToPlaybackRate(midiPitchDiff) { |
| 49 return Math.pow(2, midiPitchDiff / 12); | 49 return Math.pow(2, midiPitchDiff / 12); |
| 50 } | 50 } |
| 51 | 51 |
| 52 function createSineWaveBuffer(context, frequency, duration) { | 52 function createSineWaveBuffer(context, frequency, duration) { |
| 53 var buffer = context.createBuffer(1, duration * sampleRate, sampleRate); | 53 let buffer = context.createBuffer(1, duration * sampleRate, sampleRate); |
| 54 var data = buffer.getChannelData(0); | 54 let data = buffer.getChannelData(0); |
| 55 var omega = 2 * Math.PI * frequency / sampleRate; | 55 let omega = 2 * Math.PI * frequency / sampleRate; |
| 56 for (var i = 0; i < data.length; i++) | 56 for (let i = 0; i < data.length; i++) |
| 57 data[i] = Math.sin(omega * i); | 57 data[i] = Math.sin(omega * i); |
| 58 | 58 |
| 59 return buffer; | 59 return buffer; |
| 60 } | 60 } |
| 61 | 61 |
| 62 var context = new OfflineAudioContext(2, totalDuration * sampleRate, sampleRat e); | 62 // This is the fundamental buffer for playbackRate modulation. The duration |
| 63 | 63 // of this buffer is arbitrary but long enough to produce the sound without |
| 64 // This is the fundamental buffer for playbackRate modulation. The duration of | |
| 65 // this buffer is arbitrary but long enough to produce the sound without | |
| 66 // running short. | 64 // running short. |
| 67 var fundamentalBuffer = createSineWaveBuffer(context, pitchToFrequency(fundame ntalPitch), totalDuration); | 65 let fundamentalBuffer; |
| 68 | 66 |
| 69 // A unit test consists of 2 sources: the 'actual' source runs a buffer with | 67 // A unit test consists of 2 sources: the 'actual' source runs a buffer with |
| 70 // the playback rate modulated and the 'expected' source runs a mathmatically | 68 // the playback rate modulated and the 'expected' source runs a |
| 71 // generated sound buffer. | 69 // mathmatically generated sound buffer. |
| 72 function runUnitTest(context, noteStart, notePitch) { | 70 function runUnitTest(context, noteStart, notePitch) { |
| 73 var actualSrc = context.createBufferSource(); | 71 let actualSrc = context.createBufferSource(); |
| 74 var expectedSrc = context.createBufferSource(); | 72 let expectedSrc = context.createBufferSource(); |
| 75 var merger = context.createChannelMerger(2); | 73 let merger = context.createChannelMerger(2); |
| 76 | 74 |
| 77 actualSrc.buffer = fundamentalBuffer; | 75 actualSrc.buffer = fundamentalBuffer; |
| 78 expectedSrc.buffer = createSineWaveBuffer(context, pitchToFrequency(notePitc h), noteDuration); | 76 expectedSrc.buffer = createSineWaveBuffer(context, |
| 79 actualSrc.playbackRate.value = pitchDiffToPlaybackRate(notePitch - fundament alPitch); | 77 pitchToFrequency(notePitch), noteDuration); |
| 78 actualSrc.playbackRate.value = | |
| 79 pitchDiffToPlaybackRate(notePitch - fundamentalPitch); | |
| 80 | 80 |
| 81 actualSrc.connect(merger, 0, 0); | 81 actualSrc.connect(merger, 0, 0); |
| 82 expectedSrc.connect(merger, 0, 1); | 82 expectedSrc.connect(merger, 0, 1); |
| 83 merger.connect(context.destination); | 83 merger.connect(context.destination); |
| 84 | 84 |
| 85 actualSrc.start(noteStart); | 85 actualSrc.start(noteStart); |
| 86 actualSrc.stop(noteStart + noteDuration); | 86 actualSrc.stop(noteStart + noteDuration); |
| 87 expectedSrc.start(noteStart); | 87 expectedSrc.start(noteStart); |
| 88 expectedSrc.stop(noteStart + noteDuration); | 88 expectedSrc.stop(noteStart + noteDuration); |
| 89 } | 89 } |
| 90 | 90 |
| 91 // Schedule tests up to 60 pitches above from the fundamental pitch. | |
| 92 for (var iteration = 0; iteration < numberOfPitches; iteration++) | |
| 93 runUnitTest(context, noteDuration * iteration, fundamentalPitch + iteration) ; | |
| 94 | 91 |
| 95 // Once the rendering is complete, split the buffer into 5 octaves. Then | 92 audit.defineTask("playbackrate-test", function (taskDone) { |
| 96 // perform the SNR and the maximum difference ULP check for each octave with | 93 task.describe( |
| 97 // different constraints. | 94 "Test if AudioBufferSourceNode.playbackRate can playback at different rate s properly." |
|
hongchan
2017/01/13 17:56:02
Let's wrap this at 80 col.
Raymond Toy
2017/01/13 18:04:15
Actually this was my mistake. This file isn't con
hongchan
2017/01/13 18:07:03
Hmm. This is PS4. Where I can find the wrapped str
| |
| 98 context.startRendering().then(function (renderedBuffer) { | 95 ); |
| 99 var actual = renderedBuffer.getChannelData(0); | 96 let context = new OfflineAudioContext(2, totalDuration * |
| 100 var expected = renderedBuffer.getChannelData(1); | 97 sampleRate, |
| 101 var octaveLength = Math.floor(noteDuration * 12 * sampleRate); | 98 sampleRate); |
| 99 fundamentalBuffer = createSineWaveBuffer(context, | |
| 100 pitchToFrequency(fundamentalPitch), totalDuration); | |
| 102 | 101 |
| 103 for (var i = 0; i < numberOfPitches / 12; i++) { | 102 // Schedule tests up to 60 pitches above from the fundamental pitch. |
| 104 var start = i * octaveLength, end = (i + 1) * octaveLength; | 103 for (let iteration = 0; iteration < numberOfPitches; iteration++) |
| 105 var octaveActual = actual.subarray(start, end); | 104 runUnitTest(context, noteDuration * iteration, fundamentalPitch + |
| 106 var octaveExpected = expected.subarray(start, end); | 105 iteration); |
| 107 | 106 |
| 108 compareBuffersWithConstraints(octaveActual, octaveExpected, testConstraint s[i]); | 107 // Once the rendering is complete, split the buffer into 5 octaves. Then |
| 109 } | 108 // perform the SNR and the maximum difference ULP check for each octave |
| 109 // with different constraints. | |
| 110 context.startRendering() | |
| 111 .then(function (renderedBuffer) { | |
| 112 let actual = renderedBuffer.getChannelData(0); | |
| 113 let expected = renderedBuffer.getChannelData(1); | |
| 114 let octaveLength = Math.floor(noteDuration * 12 * sampleRate); | |
| 110 | 115 |
| 111 finishJSTest(); | 116 for (let i = 0; i < numberOfPitches / 12; i++) { |
| 117 let start = i * octaveLength, | |
| 118 let end = (i + 1) * octaveLength; | |
| 119 let octaveActual = actual.subarray(start, end); | |
| 120 let octaveExpected = expected.subarray(start, end); | |
| 121 | |
| 122 compareBuffersWithConstraints(octaveActual, octaveExpected, | |
| 123 testConstraints[i]); | |
| 124 } | |
| 125 | |
| 126 }) | |
| 127 .then(taskDone); | |
| 112 }); | 128 }); |
| 113 | 129 |
| 114 successfullyParsed = true; | 130 audit.runTasks(); |
| 115 </script> | 131 </script> |
| 116 </body> | 132 </body> |
| 117 </html> | 133 </html> |
| OLD | NEW |