Last active
November 3, 2017 15:14
-
-
Save xavriley/3c319f82d896762ee75647dfe91cdc00 to your computer and use it in GitHub Desktop.
Sonic Pi timing demo in Opal Ruby
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
// Proof of concept for blocking sleep with iteration using jsfiddle | |
// note the parallel iteration | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
async function demo() { | |
console.log("boom") | |
await sleep(1000); | |
} | |
async function demo2() { | |
while(true) { | |
await demo(); | |
} | |
} | |
async function demo3() { | |
console.log("tick") | |
await sleep(500); | |
} | |
async function demo4() { | |
while(true) { | |
await demo3(); | |
} | |
} | |
demo2(); | |
demo4(); |
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
# takes 20 seconds to run so be patient | |
start_time = Time.now.to_f | |
sched_ahead = 0.5 | |
virtual_time = start_time + sched_ahead | |
10.times do | |
sleep_time = 2 | |
# calculate an "ideal" time that we'd like to sleep for | |
# and cache it | |
virtual_time = virtual_time + sleep_time | |
# get the real time | |
# This will most likely be a few milliseconds further on | |
# than our ideal time because of computation time etc. | |
now = Time.now.to_f | |
puts now | |
# sleep for slightly less than our ideal time, | |
# taking into account the delay | |
sleep(virtual_time - now) | |
end |
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
window.AudioContext = window.AudioContext || window.webkitAudioContext; | |
/// custom buffer loader | |
/// see http://www.html5rocks.com/en/tutorials/webaudio/intro/ | |
function BufferLoader(context, urlList, callback) { | |
this.context = context; | |
this.urlList = urlList; | |
this.onload = callback; | |
this.bufferList = new Array(); | |
this.loadCount = 0; | |
} | |
BufferLoader.prototype.loadBuffer = function (url, index) { | |
// Load buffer asynchronously | |
var request = new XMLHttpRequest(); | |
request.open("GET", url, true); | |
request.responseType = "arraybuffer"; | |
var loader = this; | |
request.onload = function () { | |
// Asynchronously decode the audio file data in request.response | |
loader.context.decodeAudioData( | |
request.response, | |
function (buffer) { | |
if (!buffer) { | |
alert('error decoding file data: ' + url); | |
return; | |
} | |
loader.bufferList[index] = buffer; | |
if (++loader.loadCount == loader.urlList.length) loader.onload(loader.bufferList); | |
}, | |
function (error) { | |
console.error('decodeAudioData error', error); | |
}); | |
} | |
request.onerror = function (e) { | |
alert('BufferLoader: XHR error'); | |
console.log(e); | |
} | |
request.send(); | |
} | |
BufferLoader.prototype.load = function () { | |
for (var i = 0; i < this.urlList.length; ++i) | |
this.loadBuffer(this.urlList[i], i); | |
} | |
/// setup audio context and start loading samples | |
var actx = | |
new AudioContext(), | |
blst, | |
bLoader = new BufferLoader( | |
actx, [ | |
'https://dl.dropboxusercontent.com/s/mide1jl8ks3hdmd/drum_cymbal_closed.flac', | |
'https://dl.dropboxusercontent.com/s/mide1jl8ks3hdmd/drum_cymbal_closed.flac', | |
'https://dl.dropboxusercontent.com/s/zc5nu4pm4oree63/bd_haus.flac'], | |
done), | |
isReady = false; | |
/// start loading the samples | |
bLoader.load(); | |
/// when samples are loaded update status | |
function done(bl) { | |
blst = bl; | |
isReady = true; | |
$('#status').html('Ready!'); | |
} | |
/// this sets up chain so we can play audio | |
function play(i) { | |
var src = actx.createBufferSource(); | |
src.buffer = blst[i]; | |
src.connect(actx.destination); | |
src.start(0); | |
} | |
/// check keys | |
$(window).bind("keydown", function (key) { | |
if (!isReady) return; | |
switch (parseInt(key.which, 10)) { | |
case 65: | |
play(0); | |
break; | |
case 83: | |
play(1); | |
break; | |
case 68: | |
play(2); | |
break; | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm using this gist as a sort of work log as I try things out. I did have second thoughts around contributing to Opal based on some history around that particular project. I was going to include the following statement in my commit message but after engaging with the core committers there I agreed to use a different forum. I'm including the comment here for posterity: