var owl = owl || {};
owl.audioContext = null;
owl.webAudioApiIsAvailable = function(){
return (!!window.AudioContext || !!window.webkitAudioContext);
};
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
owl.initPatchAudio = function () {
if(owl.webAudioApiIsAvailable()){
var AudioContext = window.AudioContext || window.webkitAudioContext;
owl.audioContext = owl.audioContext || new AudioContext(); } else {
throw new Error('no web audio api');
}
var WEB_setup = Module.cwrap('WEB_setup', 'number', ['number', 'number']);
var WEB_processBlock = Module.cwrap('WEB_processBlock', 'number', ['number', 'number']);
var WEB_setParameter = Module.cwrap('WEB_setParameter', 'number', ['number', 'number']);
var WEB_getPatchName = Module.cwrap('WEB_getPatchName', 'string', []);
var WEB_getParameterName = Module.cwrap('WEB_getParameterName', 'string', ['number']);
var WEB_getMessage = Module.cwrap('WEB_getMessage', 'string', []);
var WEB_getStatus = Module.cwrap('WEB_getStatus', 'string', []);
var WEB_setButton;
var WEB_getButtons;
var WEB_processMidi;
var WEB_getParameter;
try {
WEB_setButton = Module.cwrap('WEB_setButton', 'number', ['number', 'number']);
WEB_getButtons = Module.cwrap('WEB_getButtons', 'number', []);
WEB_processMidi = Module.cwrap('WEB_processMidi', 'number', ['number', 'number', 'number', 'number']);
WEB_getParameter = Module.cwrap('WEB_getParameter', 'number', ['number']);
}catch(x){}
var that = {};
that.model = {
inputNode: null,
fileNode: null, micNode: null
};
that.vectorsize = 2048;
WEB_setup(owl.audioContext.sampleRate, that.vectorsize);
console.log("audio[fs "+owl.audioContext.sampleRate+"][bs "+that.vectorsize+"]");
for(var i = 0; i < 5; i++){
console.log("parameter "+i+": "+WEB_getParameterName(i));
}
that.getNumInputs = function () {
return 2; };
that.getNumOutputs = function () {
return 2; };
that.getMessage = function() {
return WEB_getMessage();
}
that.getStatus = function() {
return WEB_getStatus();
}
that.compute = function (e) {
var dspOutChans = HEAP32.subarray(that.outs >> 2, (that.outs + that.numOut * that.ptrsize) >> 2);
var dspInChans = HEAP32.subarray(that.ins >> 2, (that.ins + that.ins * that.ptrsize) >> 2);
for (var i = 0; i < that.numIn; i++)
{
var input = e.inputBuffer.getChannelData(i);
var dspInput = HEAPF32.subarray(dspInChans[i] >> 2, (dspInChans[i] + that.vectorsize * that.ptrsize) >> 2);
for (var j = 0; j < input.length; j++) {
dspInput[j] = input[j];
}
}
WEB_processBlock(that.ins, that.outs);
for(var i = 0; i < that.numOut; i++){
var output = e.outputBuffer.getChannelData(i);
var dspOutput = HEAPF32.subarray(dspOutChans[i] >> 2, (dspOutChans[i] + that.vectorsize * that.ptrsize) >> 2);
for (var j = 0; j < output.length; j++) {
output[j] = dspOutput[j];
}
}
return that;
};
that.connectInput = function (node) {
that.clearInput();
node.connect(that.scriptNode);
that.model.inputNode = node;
}
that.clearInput = function () {
if (that.model.inputNode) {
that.model.inputNode.disconnect(that.scriptNode);
}
that.model.inputNode = null;
}
that.useMicrophoneInput = function () {
if (that.model.micNode) {
that.connectInput(that.model.micNode);
} else {
navigator.getUserMedia.call(navigator, {audio: true}, function (stream) {
that.model.micNode = owl.audioContext.createMediaStreamSource(stream);
that.connectInput(that.model.micNode);
}, function (err) {
console.error(err);
});
}
}
that.useFileInput = function (audioNode) {
that.model.fileNode = that.model.fileNode || owl.audioContext.createMediaElementSource(audioNode);
that.connectInput(that.model.fileNode);
}
that.onFileSelect = function (files) {
var fileUrl = files[0] ? URL.createObjectURL(files[0]) : '';
var audioElement = document.getElementById('patch-test-audio');
audioElement.src = fileUrl;
}
that.getParameterName = function(pid){
return WEB_getParameterName(pid);
}
that.getPatchName = function(){
return WEB_getPatchName();
}
that.setButton = function(key, value) {
if(WEB_setButton)
WEB_setButton(key, value);
return that;
};
that.getParameter = function(key) {
if(WEB_getParameter)
return WEB_getParameter(key);
return 0.5;
};
that.update = function (key, value) {
if(key < 80){
WEB_setParameter(key, value);
}else if(key == 80){
that.setButton(1, value);
that.setButton(4, value);
}else{
that.setButton(key-80+4, value);
}
return that;
};
that.getButtons = function() {
if(WEB_getButtons){
return WEB_getButtons();
} else {
return 0;
}
};
that.getPushButtonLedColour = function(){
if(WEB_getButtons){
var buttonState = WEB_getButtons();
if(buttonState & 0x04){ return 'green';
}
if(buttonState & 0x08){ return 'red';
}
}
return null;
};
that.connectToOutput = function(options){
options = options || {};
if(options.outputs === 1){
var splitter = owl.audioContext.createChannelSplitter(2);
that.scriptNode.connect(splitter);
that.outputNode = splitter;
} else {
that.outputNode = that.scriptNode;
}
that.outputNode.connect(owl.audioContext.destination);
};
that.disconnectFromOutput = function(){
that.outputNode.disconnect();
};
that.processMidi = function(status, d1, d2) {
var port = 0;
if(WEB_processMidi){
return WEB_processMidi(port, status, d1, d2);
} else {
return 0;
}
}
that.ptrsize = 4; that.samplesize = 4;
that.numIn = that.getNumInputs();
that.numOut = that.getNumOutputs();
that.scriptNode = owl.audioContext.createScriptProcessor(that.vectorsize, that.numIn, that.numOut);
that.scriptNode.onaudioprocess = that.compute;
that.ins = Module._malloc(that.ptrsize * that.numIn);
for (var i = 0; i < that.numIn; i++) {
HEAP32[(that.ins >> 2) + i] = Module._malloc(that.vectorsize * that.samplesize);
}
that.outs = Module._malloc(that.ptrsize * that.numOut);
for (var i = 0; i < that.numOut; i++) {
HEAP32[(that.outs >> 2) + i] = Module._malloc(that.vectorsize * that.samplesize);
}
return that;
};