Created
March 2, 2018 20:15
-
-
Save syncopika/329d06aff900de6eef491e0c3b9ee8ca to your computer and use it in GitHub Desktop.
web audio demo - scheduling a sequence of notes and getting smooth notes
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
<!doctype html> | |
<html> | |
<head> | |
</head> | |
<body> | |
<p> testing Web Audio... </p> | |
<button onclick='test()'> play </button> | |
</body> | |
<script> | |
var ctx = new AudioContext(); | |
gainNode = ctx.createGain(); | |
gainNode.connect(ctx.destination); | |
gainNode.gain.setTargetAtTime(0, 0, 0); // set gain to 0 initially | |
var nextTime; // hold the next time an oscillator needs to play | |
// the beginning notes to 'Sand Canyon'. taken from the demo json file found in my piano_roll_browser application. | |
var notes = [ | |
{"freq":349.23,"duration":200,"block":{"id":"F4col_0","length":"eighth","volume":"0.2","style":"default"}}, | |
{"freq":0,"duration":100,"block":{"id":null,"length":"sixteenth","volume":"0.3","style":"default"}}, | |
{"freq":523.25,"duration":100,"block":{"id":"C5col_1-2","length":"sixteenth","volume":"0.2","style":"default"}}, | |
{"freq":493.88,"duration":200,"block":{"id":"B4col_2","length":"eighth","volume":"0.8","style":"default"}}, | |
{"freq":523.25,"duration":200,"block":{"id":"C5col_3","length":"eighth","volume":"0.2","style":"default"}}, | |
{"freq":698.46,"duration":200,"block":{"id":"F5col_4","length":"eighth","volume":"0.2","style":"glide"}}, | |
{"freq":622.25,"duration":200,"block":{"id":"Eb5col_5","length":"eighth","volume":"0.6","style":"default"}}, | |
{"freq":587.33,"duration":200,"block":{"id":"D5col_6","length":"eighth","volume":"0.6","style":"default"}}, | |
{"freq":523.25,"duration":200,"block":{"id":"C5col_7","length":"eighth","volume":"0.2","style":"default"}}, | |
{"freq":493.88,"duration":200,"block":{"id":"B4col_8","length":"eighth","volume":"0.2","style":"legato"}}, | |
{"freq":523.25,"duration":100,"block":{"id":"C5col_9-1","length":"sixteenth","volume":"0.2","style":"default"}}, | |
{"freq":0,"duration":100,"block":{"id":null,"length":"sixteenth","volume":"0.3","style":"default"}}, | |
{"freq":0,"duration":200,"block":{"id":null,"length":"eighth","volume":"0.3","style":"default"}} | |
]; | |
function test(){ | |
var counter = 0; | |
while(counter < notes.length){ | |
var note = notes[counter]; | |
var currTime = ctx.currentTime; | |
if(counter == 0){ | |
nextTime = ctx.currentTime; | |
} | |
// create a new oscillator for each note | |
var osc = ctx.createOscillator(); | |
osc.type = 'sine'; | |
osc.connect(gainNode); | |
//osc.connect(ctx.destination); | |
// set frequency and volume | |
//osc.frequency.value = note.freq; | |
osc.frequency.setTargetAtTime(note.freq, 0.01, 0); | |
//gainNode.gain.value = note.block.volume; // deprecated way | |
// when you use setTargetAtTime to ramp up to a volume, you need to also ramp back down | |
// so there needs to be a corresponding setTargetAtTime | |
gainNode.gain.setTargetAtTime(parseFloat(note.block.volume), nextTime + .002, 0.002); | |
// using an exponential ramp sounds a bit like an electronic stab wave | |
// using a linear ramp sounds a bit like a mallet instrument | |
//gainNode.gain.exponentialRampToValueAtTime(note.block.volume, nextTime + 0.002); | |
osc.start(nextTime); | |
//gainNode.gain.exponentialRampToValueAtTime(0.01, nextTime + (note.duration/1000) - 0.002); | |
gainNode.gain.setTargetAtTime(0, nextTime + (note.duration/1000) - .008, 0.0020); | |
osc.stop(nextTime + (note.duration/1000)); | |
nextTime = nextTime + (note.duration/1000); | |
counter++; | |
} | |
} | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment