Last active
February 3, 2016 00:12
-
-
Save hoch/391d94ffd8f00c432c63 to your computer and use it in GitHub Desktop.
Chromium Web Audio Layout Test prototypes for Canopy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @channels 3 | |
// @sampleRate 128000 | |
// @duration 1.5 | |
function pitchToFrequency(pitch) { | |
return 440 * Math.pow(2, (Math.floor(pitch)-69)/12); | |
} | |
function pitchToPlaybackRate(pitch) { | |
return Math.pow(2, pitch/12); | |
} | |
function createSineWaveBuffer(context, frequency, duration) { | |
var length = duration * context.sampleRate; | |
var buffer = context.createBuffer(1, length, context.sampleRate); | |
var data = buffer.getChannelData(0); | |
var base = 2 * Math.PI * frequency / context.sampleRate; | |
for (var i = 0; i < data.length; i++) | |
data[i] = Math.sin(base * i); | |
return buffer; | |
} | |
var basePitch = 36; | |
var baseFrequency = pitchToFrequency(basePitch); | |
var testBuffer = createSineWaveBuffer(context, baseFrequency, 2 / baseFrequency); | |
console.log(testBuffer.duration); | |
var unitDuration = 0.025; | |
function runUnitTest(context, unitStart, unitPitch) { | |
var source1 = context.createBufferSource(); | |
var source2 = context.createBufferSource(); | |
var inverter = context.createGain(); | |
var merger = context.createChannelMerger(3); | |
var env = context.createGain(); | |
var expectedBuffer = createSineWaveBuffer(context, pitchToFrequency(unitPitch), unitDuration); | |
var targetRate = pitchToPlaybackRate(unitPitch - basePitch); | |
source1.buffer = expectedBuffer; | |
source1.loop = true; | |
source2.buffer = testBuffer; | |
source2.playbackRate.value = targetRate; | |
source2.loop = true; | |
source2.loopStart = 0.5 * testBuffer.duration; | |
source2.loopEnd = testBuffer.duration; | |
inverter.gain.value = -1.0; | |
source1.connect(merger, 0, 0); | |
source2.connect(merger, 0, 1); | |
source1.connect(merger, 0, 2); | |
source2.connect(inverter); | |
inverter.connect(merger, 0, 2); | |
merger.connect(env); | |
env.connect(context.destination); | |
source1.start(unitStart); | |
source1.stop(unitStart + unitDuration); | |
source2.start(unitStart); | |
source2.stop(unitStart + unitDuration); | |
// env.gain.setValueAtTime(1.0, unitStart); | |
// env.gain.setValueAtTime(1.0, unitStart + unitDuration - 0.005); | |
// env.gain.linearRampToValueAtTime(0.0, unitStart + unitDuration); | |
} | |
for (var iteration = 0; iteration < 60; iteration++) { | |
(function (i) { | |
context.suspend(unitDuration * i).then(function () { | |
runUnitTest(context, unitDuration * i, basePitch + i); | |
context.resume(); | |
}); | |
})(iteration); | |
} | |
context.oncomplete = function (event) { | |
var data = event.renderedBuffer.getChannelData(2); | |
var maxDiff = 0, index = -1; | |
for (var i = 0; i < data.length; i++) { | |
var diff = Math.abs(data[i]); | |
if (diff > maxDiff) { | |
maxDiff = diff; | |
index = i; | |
} | |
} | |
console.log('MAXDIFF = ' + maxDiff.toExponential() + ' (' + index + ')'); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @sampleRate 44160 | |
// @duration 1.5 | |
function pitchToFrequency(pitch) { | |
return 440 * Math.pow(2, (Math.floor(pitch)-69)/12); | |
} | |
function pitchToRate(pitch) { | |
return Math.pow(2, pitch/12); | |
} | |
function createSineWaveBuffer(context, frequency, duration) { | |
var length = duration * context.sampleRate; | |
var buffer = context.createBuffer(1, length, context.sampleRate); | |
var data = buffer.getChannelData(0); | |
var phase = 0, base = 2 * Math.PI * frequency / context.sampleRate; | |
for (var i = 0; i < length; i++) | |
data[i] = Math.sin(base * i); | |
return buffer; | |
} | |
var testBuffer = createSineWaveBuffer(context, pitchToFrequency(36), 5); | |
var testDuration = 0.025; | |
function test(context, testStart, testPitch) { | |
var source1 = context.createBufferSource(); | |
var source2 = context.createBufferSource(); | |
var inverter = context.createGain(); | |
source1.buffer = createSineWaveBuffer(context, pitchToFrequency(testPitch), testDuration); | |
source2.buffer = testBuffer; | |
source2.playbackRate.value = pitchToRate(testPitch - 36); | |
inverter.gain.value = -1.0; | |
source1.connect(context.destination); | |
source2.connect(inverter) | |
inverter.connect(context.destination); | |
source1.start(testStart); | |
source1.stop(testStart + testDuration); | |
source2.start(testStart); | |
source2.stop(testStart + testDuration); | |
} | |
function onsuspended(iteration) { | |
return function () { | |
console.log('pitch = ', 36 + iteration); | |
test(context, testDuration * iteration, 36 + iteration); | |
context.resume(); | |
}; | |
} | |
// batch scheduling | |
for (var s = 0; s < 60; s++) { | |
context.suspend(testDuration * s).then(onsuspended(s)); | |
} | |
context.oncomplete = function (event) { | |
var data = event.renderedBuffer.getChannelData(0); | |
var maxDiff = 0; | |
for (var i = 0; i < data.length; i++) { | |
var diff = Math.abs(data[i]); | |
if (diff > maxDiff) | |
maxDiff = diff; | |
} | |
console.log("MAXDIFF = ", maxDiff); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment