Commit a2a106f8 authored by Jakub Fiala's avatar Jakub Fiala

merged changes from master

parents 351db365 292fe4b2
# change '../../em++' to path to em++ in emscriten folder
# change '../../em++' to path to em++ in emscripten folder
EMSCR=../../em++
# ----------------------------------------
......
......@@ -33363,26 +33363,130 @@ maximJs.maxiTools.removePaddingFromBase64 = function(input) {
return input;
}
maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
maximJs.maxiAudio = function() {
this.numChannels = 2;
this.output = 0;
this.context = null;
this.source = null;
this.analyser = null;
this.jsProcessor = null;
this.initDone = false;
};
maximJs.maxiAudio.play = function(){};
// don't really need setup??
maximJs.maxiAudio.setup = function(){
console.log("non-overrided setup");
};
maximJs.maxiAudio.prototype.getNumChannels = function(){
return this.numChannels;
};
// isArray should be second param really
// set num channels and set output as an array
// use this if you want to change number of channels
maximJs.maxiAudio.prototype.setNumChannels = function(isArray, numChannels_){
this.numChannels = numChannels_;
this.outputIsArray(isArray, numChannels_);
this.resetAudio();
};
// use this if you want to keep num of outputs but change
// method e.g. array or not
maximJs.maxiAudio.prototype.outputIsArray = function(isArray){
if(isArray){
this.output = new Array(this.numChannels);
for(var i = 0; i < this.numChannels; i++){
this.output[i] = 0;
}
} else {
this.output = 0;
}
};
maximJs.maxiAudio.prototype.init = function() {
// Temporary patch until all browsers support unprefixed context.
this.context = new (window.AudioContext || window.webkitAudioContext)();
this.source = this.context.createBufferSource();
this.jsProcessor = this.context.createScriptProcessor(4096, this.numChannels, this.numChannels);
// var process = this.process;
this.jsProcessor.onaudioprocess = function(event) {
var numChannels = event.outputBuffer.numberOfChannels;
var outputLength = event.outputBuffer.getChannelData(0).length;
// console.log("n");
for (var i = 0; i < outputLength; ++i) {
this.play();
if(this.output instanceof Array){
for (var channel = 0; channel < numChannels; channel++) {
event.outputBuffer.getChannelData(channel)[i] = this.output[channel];
}
}
else
{
for (var channel = 0; channel < numChannels; channel++) {
event.outputBuffer.getChannelData(channel)[i] = this.output;
}
}
}
}
.bind(this)
;
this.analyser = this.context.createAnalyser();
this.analyser.fftSize = 2048;
// Connect the processing graph: source -> jsProcessor -> analyser -> destination
this.source.connect(this.jsProcessor);
this.jsProcessor.connect(this.analyser);
this.analyser.connect(this.context.destination);
this.initDone = true;
};
maximJs.maxiAudio.prototype.resetAudio = function(){
if(this.initDone){
this.source.disconnect();
this.jsProcessor.disconnect();
this.analyser.disconnect();
}
this.init();
};
// option to load sample if a different context is used
maximJs.maxiAudio.prototype.loadSample = function(url, samplePlayer, contextIn) {
var data = [];
var context;
window.AudioContext = window.AudioContext || window.webkitAudioContext;
if(!contextIn){
context = new AudioContext();
context = this.context;
} else {
context = contextIn;
}
samplePlayer.clear();
//check if url is actually a base64-encoded string
var b64 = maximJs.maxiTools.getBase64(url);
if (b64) {
//convert to arraybuffer
//modified version of this:
// https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js
var ab_bytes = (b64.length/4) * 3;
var arrayBuffer = new ArrayBuffer(ab_bytes);
b64 = this.removePaddingFromBase64(this.removePaddingFromBase64(b64));
b64 = maximJs.maxiTools.removePaddingFromBase64(maximJs.maxiTools.removePaddingFromBase64(b64));
var bytes = parseInt((b64.length / 4) * 3, 10);
......@@ -33397,10 +33501,11 @@ maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
b64 = b64.replace(/[^A-Za-z0-9\+\/\=]/g, "");
for (i=0; i<bytes; i+=3) {
enc1 = this._keyStr.indexOf(b64.charAt(j++));
enc2 = this._keyStr.indexOf(b64.charAt(j++));
enc3 = this._keyStr.indexOf(b64.charAt(j++));
enc4 = this._keyStr.indexOf(b64.charAt(j++));
//get the 3 octects in 4 ascii chars
enc1 = maximJs.maxiTools._keyStr.indexOf(b64.charAt(j++));
enc2 = maximJs.maxiTools._keyStr.indexOf(b64.charAt(j++));
enc3 = maximJs.maxiTools._keyStr.indexOf(b64.charAt(j++));
enc4 = maximJs.maxiTools._keyStr.indexOf(b64.charAt(j++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
......@@ -33414,16 +33519,20 @@ maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
context.decodeAudioData(
arrayBuffer,
function(buffer) {
// source.buffer = buffer;
// source.loop = true;
// source.start(0);
data = buffer.getChannelData(0);
if(data){
var myBufferData = new Module.VectorDouble();
// Module.vectorTools.clearVectorDbl(myBufferData);
for(var n = 0; n < data.length; n++){
myBufferData.push_back(data[n]);
}
samplePlayer.setSample(myBufferData);
samplePlayer.setSample(myBufferData/*, context.sampleRate*/);
}
},
......@@ -33436,6 +33545,7 @@ maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
}
else {
// Load asynchronously
var request = new XMLHttpRequest();
request.addEventListener("load",
function (evt) {
......@@ -33449,16 +33559,20 @@ maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
context.decodeAudioData(
request.response,
function(buffer) {
// source.buffer = buffer;
// source.loop = true;
// source.start(0);
data = buffer.getChannelData(0);
if(data){
var myBufferData = new Module.VectorDouble();
// Module.vectorTools.clearVectorDbl(myBufferData);
for(var n = 0; n < data.length; n++){
myBufferData.push_back(data[n]);
}
samplePlayer.setSample(myBufferData);
samplePlayer.setSample(myBufferData/*, context.sampleRate*/);
}
},
......@@ -33475,107 +33589,5 @@ maximJs.maxiTools.loadSample = function(url, samplePlayer, contextIn) {
};
// maximJs.maxiTools.loadSample = (function(url, samplePlayer, contextIn) {
// var data = [];
// var context;
// if (!contextIn) {
// context = new (window.AudioContext || window.webkitAudioContext);
// } else {
// context = contextIn;
// }
// samplePlayer.clear();
// var request = new XMLHttpRequest;
// request.addEventListener("load", (function(evt) {
// console.log("The transfer is complete.");
// }));
// request.open("GET", url, true);
// request.responseType = "arraybuffer";
// request.onload = (function() {
// context.decodeAudioData(request.response, (function(buffer) {
// data = buffer.getChannelData(0);
// if (data) {
// var myBufferData = new Module.VectorDouble;
// for (var n = 0; n < data.length; n++) {
// myBufferData.push_back(data[n]);
// }
// samplePlayer.setSample(myBufferData);
// }
// }), (function(buffer) {
// console.log("Error decoding source!");
// }));
// });
// request.send();
// });
maximJs.maxiAudio = (function() {
var numChannels = 2;
var bufferSize = 1024;
var output = 0;
this.context = null;
this.source = null;
this.analyser = null;
this.jsProcessor = null;
var initDone = false;
this.play = (function() {});
this.setup = (function() {
console.log("non-overrided setup");
});
this.getNumChannels = (function() {
return numChannels;
});
this.setNumChannels = (function(isArray, numChannels_) {
numChannels = numChannels_;
this.outputIsArray(isArray, numChannels_);
this.resetAudio();
});
this.outputIsArray = (function(isArray) {
if (isArray) {
maximJs.maxiAudio.output = new Array(numChannels);
for (var i = 0; i < numChannels; i++) {
maximJs.maxiAudio.output[i] = 0;
}
} else {
maximJs.maxiAudio.output = 0;
}
});
var process = (function(event) {
var numChannels = event.outputBuffer.numberOfChannels;
var outputLength = event.outputBuffer.getChannelData(0).length;
for (var i = 0; i < outputLength; ++i) {
maximJs.maxiAudio.play();
if (maximJs.maxiAudio.output instanceof Array) {
for (var channel = 0; channel < numChannels; channel++) {
event.outputBuffer.getChannelData(channel)[i] = maximJs.maxiAudio.output[channel];
}
} else {
for (var channel = 0; channel < numChannels; channel++) {
event.outputBuffer.getChannelData(channel)[i] = maximJs.maxiAudio.output;
}
}
}
});
this.resetAudio = (function() {
if (initDone) {
this.source.disconnect();
this.jsProcessor.disconnect();
this.analyser.disconnect();
}
this.init();
});
this.init = (function() {
this.context = new (window.AudioContext || window.webkitAudioContext);
this.source = this.context.createBufferSource();
this.jsProcessor = this.context.createScriptProcessor(2048, numChannels, numChannels);
this.jsProcessor.onaudioprocess = process;
this.analyser = this.context.createAnalyser();
this.analyser.fftSize = 2048;
this.source.connect(this.jsProcessor);
this.jsProcessor.connect(this.analyser);
this.analyser.connect(this.context.destination);
initDone = true;
});
return this;
})();
......@@ -44,7 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
var myCounter = new maximJs.maxiOsc(); //these oscillators will help us count and play sound
var mySwitchableOsc = new maximJs.maxiOsc();//
......@@ -64,7 +65,7 @@ myEnvelope.setSustain(1);
myEnvelope.setRelease(1000);
maximJs.maxiAudio.play = function(){
audio.play = function(){
myCurrentVolume=myEnvelope.adsr(1.,myEnvelope.trigger);
......@@ -85,7 +86,7 @@ maximJs.maxiAudio.play = function(){
// The last input is the resonance.
myFilteredOutput=myFilter.lores(myOscOutput,myCurrentVolume*1000,10);
output=myFilteredOutput;//left speaker
this.output=myFilteredOutput;//left speaker
}
......@@ -102,6 +103,9 @@ maximJs.maxiAudio.play = function(){
</p>
<pre class="prettyprint lang-js linenums:true" id="quine" style="border:4px solid #88c" >
var audio = new maximJs.maxiAudio();
audio.init();
var myCounter = new maximJs.maxiOsc(); //these oscillators will help us count and play sound
var mySwitchableOsc = new maximJs.maxiOsc();//
......@@ -112,15 +116,15 @@ var myOscOutput,myFilteredOutput;//
var myEnvelope = new maximJs.maxiEnv();
var myFilter = new maximJs.maxiFilter();
function setup(){
//Timing is in ms
myEnvelope.setAttack(0);
myEnvelope.setDecay(1); // Needs to be at least 1
myEnvelope.setSustain(1);
myEnvelope.setRelease(1000);
}
myEnvelope.setAttack(0);
myEnvelope.setDecay(1); // Needs to be at least 1
myEnvelope.setSustain(1);
myEnvelope.setRelease(1000);
maximJs.maxiAudio.play = function(){
audio.play = function(){
myCurrentVolume=myEnvelope.adsr(1.,myEnvelope.trigger);
......@@ -141,7 +145,7 @@ maximJs.maxiAudio.play = function(){
// The last input is the resonance.
myFilteredOutput=myFilter.lores(myOscOutput,myCurrentVolume*1000,10);
output=myFilteredOutput;//left speaker
this.output=myFilteredOutput;//left speaker
}
</pre>
</body></html>
......@@ -43,9 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
// change output to an array
maximJs.maxiAudio.outputIsArray(true, 2);
audio.outputIsArray(true, 2);
var myOsc = new maximJs.maxiOsc();
var myAutoPanner = new maximJs.maxiOsc();
......@@ -54,10 +55,10 @@ var myOutputs = new maximJs.maxiMix();//this is the stereo mixer channel.
maximJs.maxiAudio.play = function(){
audio.play = function(){
myOutputs.stereo(myOsc.noise(),myStereoOutput,(myAutoPanner.sinewave(1)+1)/2);//Stereo, Quad or 8 Channel. Specify the input to be mixed, the output[numberofchannels], and the pan (0-1,equal power).
output[0]=myStereoOutput.get(0);//When working with mixing, you need to specify the outputs explicitly
output[1]=myStereoOutput.get(1);//
this.output[0]=myStereoOutput.get(0);//When working with mixing, you need to specify the outputs explicitly
this.output[1]=myStereoOutput.get(1);//
}
</script>
......@@ -73,24 +74,23 @@ maximJs.maxiAudio.play = function(){
</p>
<pre class="prettyprint lang-js linenums:true" id="quine" style="border:4px solid #88c" >
var myOsc = new maximJs.maxiOsc();
var myAutoPanner = new maximJs.maxiOsc();
var myStereoOutput = GetArrayAsVectorDbl([0,0]);
var myOutputs = new maximJs.maxiMix();//this is the stereo mixer channel.
var audio = new maximJs.maxiAudio();
audio.init();
// change output to an array
audio.outputIsArray(true, 2);
var myOsc = new maximJs.maxiOsc();
var myAutoPanner = new maximJs.maxiOsc();
var myStereoOutput = maximJs.maxiTools.getArrayAsVectorDbl([0,0]);
var myOutputs = new maximJs.maxiMix();//this is the stereo mixer channel.
function setup(){
// change output to an array
// setNumOutputChannels(2);
OutputIsArray(true, 2);
}
maximJs.maxiAudio.play = function(){
audio.play = function(){
myOutputs.stereo(myOsc.noise(),myStereoOutput,(myAutoPanner.sinewave(1)+1)/2);//Stereo, Quad or 8 Channel. Specify the input to be mixed, the output[numberofchannels], and the pan (0-1,equal power).
this.output[0]=myStereoOutput.get(0);//When working with mixing, you need to specify the outputs explicitly
this.output[1]=myStereoOutput.get(1);//
}
myOutputs.stereo(myOsc.noise(),myStereoOutput,(myAutoPanner.sinewave(1)+1)/2);//Stereo, Quad or 8 Channel. Specify the input to be mixed, the output[numberofchannels], and the pan (0-1,equal power).
output[0]=myStereoOutput.get(0);//When working with mixing, you need to specify the outputs explicitly
output[1]=myStereoOutput.get(1);//
}
</pre>
</body></html>
......@@ -42,23 +42,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
var samplePlayer = new maximJs.maxiSample();
var mySine = new maximJs.maxiOsc();
maximJs.maxiTools.loadSample("audio/beat2.wav", samplePlayer);
// maximJs.maxiTools.loadSample("audio/beat2.wav", samplePlayer, maximJs.maxiAudio.context);
// load sample to 'samplePlayer' using 'audio' object
audio.loadSample("audio/beat2.wav", samplePlayer);
maximJs.maxiAudio.play = function(){
audio.play = function(){
// this is necessary as file loading may not complete in setup
if(samplePlayer.isReady()){
output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// output=samplePlayer.play(0.69) ;//play the file with a speed setting. 1. is normal speed.
// output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
// output=samplePlayer.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
}
this.output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// this.output=samplePlayer.play(0.69) ;//play the file with a speed setting. 1. is normal speed.
// this.output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
// this.output=samplePlayer.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
}
}
......@@ -75,21 +75,23 @@ maximJs.maxiAudio.play = function(){
</p>
<pre class="prettyprint lang-js linenums:true" id="quine" style="border:4px solid #88c" >
var audio = new maximJs.maxiAudio();
audio.init();
var samplePlayer = new maximJs.maxiSample();
var mySine = new maximJs.maxiOsc();
function setup(){
loadSample("./beat2.wav", samplePlayer);
}
// load sample using 'audio' object
audio.loadSample("audio/beat2.wav", samplePlayer);
maximJs.maxiAudio.play = function(){
audio.play = function(){
// this is necessary as file loading may not complete in setup
if(samplePlayer.isReady()){
output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// output=samplePlayer.play(0.69) ;//play the file with a speed setting. 1. is normal speed.
// output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
// output=samplePlayer.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
}
this.output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// this.output=samplePlayer.play(0.69) ;//play the file with a speed setting. 1. is normal speed.
// this.output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
// this.output=samplePlayer.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
}
}
</pre>
</body></html>
\ No newline at end of file
......@@ -43,7 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
var a = new maximJs.maxiOsc();
var xs = [0,0,0], ys = [0,0,0];
......@@ -83,12 +84,12 @@ a2 = 1 - alpha;
maximJs.maxiAudio.play = function() {//this is where the magic happens. Very slow magic.
audio.play = function() {//this is where the magic happens. Very slow magic.
xs[0] = mySwitchableOsc.sawn(400);
ys[0] = (b0/a0)*xs[0] + (b1/a0)*xs[1] + (b2/a0)*xs[2]
- (a1/a0)*ys[1] - (a2/a0)*ys[2];
output = ys[0];
this.output = ys[0];
ys[2] = ys[1]; ys[1] = ys[0];
xs[2] = xs[1]; xs[1] = xs[0];
......@@ -108,7 +109,8 @@ maximJs.maxiAudio.play = function() {//this is where the magic happens. Very slo
</p>
<pre class="prettyprint lang-js linenums:true" id="quine" style="border:4px solid #88c" >
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
var a = new maximJs.maxiOsc();
var xs = [0,0,0], ys = [0,0,0];
......@@ -148,15 +150,17 @@ a2 = 1 - alpha;
maximJs.maxiAudio.play = function() {//this is where the magic happens. Very slow magic.
xs[0] = mySwitchableOsc.sawn(400);
ys[0] = (b0/a0)*xs[0] + (b1/a0)*xs[1] + (b2/a0)*xs[2]
- (a1/a0)*ys[1] - (a2/a0)*ys[2];
output = ys[0];
ys[2] = ys[1]; ys[1] = ys[0];
xs[2] = xs[1]; xs[1] = xs[0];
audio.play = function() {//this is where the magic happens. Very slow magic.
xs[0] = mySwitchableOsc.sawn(400);
ys[0] = (b0/a0)*xs[0] + (b1/a0)*xs[1] + (b2/a0)*xs[2]
- (a1/a0)*ys[1] - (a2/a0)*ys[2];
this.output = ys[0];
ys[2] = ys[1]; ys[1] = ys[0];
xs[2] = xs[1]; xs[1] = xs[0];
}
</pre>
</body></html>
......@@ -44,7 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
//This shows how to use maximilian to build a monophonic synth
//These are the synthesiser bits
......@@ -69,7 +70,7 @@ ADSR.setSustain(1);
ADSR.setRelease(1000);
maximJs.maxiAudio.play = function(){
audio.play = function(){
//so this first bit is just a basic metronome so we can hear what we're doing.
currentCount=Math.round(timer.phasor(0.5));//this sets up a metronome that ticks every 2 seconds
......@@ -96,7 +97,7 @@ maximJs.maxiAudio.play = function(){
var finalSound=VCFout*ADSRout;//finally we add the ADSR as an amplitude modulator
ADSR.trigger=0;
output=finalSound;
this.output=finalSound;
}
</script>
......@@ -111,7 +112,7 @@ maximJs.maxiAudio.play = function(){
</p>
<pre class="prettyprint lang-js linenums:true" id="quine" style="border:4px solid #88c" >
maximJs.maxiAudio.init();
audio.init();
//This shows how to use maximilian to build a monophonic synth
//These are the synthesiser bits
......@@ -121,7 +122,6 @@ var LFO1 = new maximJs.maxiOsc();
var LFO2 = new maximJs.maxiOsc();
var VCF = new maximJs.maxiFilter();
var ADSR = new maximJs.maxiEnv();
//This is a bunch of control signals so that we can hear something
......@@ -137,7 +137,7 @@ ADSR.setSustain(1);
ADSR.setRelease(1000);
maximJs.maxiAudio.play = function(){
audio.play = function(){
//so this first bit is just a basic metronome so we can hear what we're doing.
currentCount=Math.round(timer.phasor(0.5));//this sets up a metronome that ticks every 2 seconds
......@@ -164,7 +164,7 @@ maximJs.maxiAudio.play = function(){
var finalSound=VCFout*ADSRout;//finally we add the ADSR as an amplitude modulator
ADSR.trigger=0;
output=finalSound;
this.output=finalSound;
}
</pre>
</body></html>
......@@ -44,23 +44,45 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<!-- Our javascript code -->
<script type="text/javascript">
maximJs.maxiAudio.init();
var audio = new maximJs.maxiAudio();
audio.init();
// change output to an array
maximJs.maxiAudio.outputIsArray(true, 2);
audio.outputIsArray(true, 2);
//This shows how to use maximilian to build a polyphonic synth.
// Chrome doesn't like this one for some reason