Skip to content

Instantly share code, notes, and snippets.

@xavriley
Last active November 3, 2017 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xavriley/3c319f82d896762ee75647dfe91cdc00 to your computer and use it in GitHub Desktop.
Save xavriley/3c319f82d896762ee75647dfe91cdc00 to your computer and use it in GitHub Desktop.
Sonic Pi timing demo in Opal Ruby
// 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();
# 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
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;
}
})
@xavriley
Copy link
Author

xavriley commented Nov 3, 2017

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:

Finally, if my contributions to the project are accepted I agree to the
terms of the code of conduct. For my own peace of mind though, I would
like to go on record to say that I don't share the views of other
maintainers on the issue of transgender discrimination in particular.

I don't want to make any more political statements than necessary as
this project has already hosted a great deal of discussion. However, as a sibling of
mine is a) currently transitioning gender and b) working towards a career in coding I
don't feel I can ignore the issue with a clear conscience.

Rather than walking away or ignoring the project I have chosen to engage and to
contribute if I can. My view is that I'd like to move forward with
positivity but this doesn't imply that I condone or support the views
I've seen expressed by maintainers elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment