js303/public/js/js303.js
2015-01-14 20:12:11 +01:00

275 lines
7.0 KiB
JavaScript

(function(){ // TODO: Fix sluggishness in wrapper
var audiotimer;
var synth;
var pitchmode=false;
var currentstep=0;
function changestep(pos) {
currentstep=pos;
$("#stepnumber").css("background-position","-"+(pos*50)+"px 0px");
var pitch = synth.pattern[pos][0]-40;
$("#cled").toggleClass("on",pitch==0);
$("#dbled").toggleClass("on",pitch==1);
$("#dled").toggleClass("on",pitch==2);
$("#ebled").toggleClass("on",pitch==3);
$("#eled").toggleClass("on",pitch==4);
$("#fled").toggleClass("on",pitch==5);
$("#gbled").toggleClass("on",pitch==6);
$("#gled").toggleClass("on",pitch==7);
$("#abled").toggleClass("on",pitch==8);
$("#aled").toggleClass("on",pitch==9);
$("#bbled").toggleClass("on",pitch==10);
$("#bled").toggleClass("on",pitch==11);
$("#ccled").toggleClass("on",pitch==12);
$("#accentled").toggleClass("on",synth.pattern[pos][1]);
$("#slideled").toggleClass("on",synth.pattern[pos][2]);
$("#noteled").toggleClass("on",synth.pattern[pos][3]);
$("#restled").toggleClass("on",!synth.pattern[pos][3]);
$("#downled").toggleClass("on",synth.pattern[pos][4]);
$("#upled").toggleClass("on",synth.pattern[pos][5]);
}
$(function(){
// init synth
synth = new TB303;
if (typeof song !== "undefined") {
synth.unserialize(song);
}
// set up interface
$("#tempo").dial({
numImages: 41,
imageWidth: 36,
min: 20.0,
max: 200.0,
value: synth.tempo,
unitsPerPixel: 1,
change: function(e,u){
synth.settempo(u.value);
}
});
$("#threshold").dial({
numImages: 41,
imageWidth: 36,
min: 0.0,
max: 1.0,
value: synth.dist_threshold,
unitsPerPixel: 0.01,
change: function(e,u){
synth.setdistthreshold(u.value);
}
});
$("#shape").dial({
numImages: 41,
imageWidth: 36,
min: 0.0,
max: 1.0,
value: synth.dist_shape,
unitsPerPixel: 0.01,
change: function(e,u){
synth.dist_shape = u.value;
}
});
$("#tuning").dial({
numImages: 41,
imageWidth: 36,
min: -12.0,
max: 12.0,
value: synth.tuning,
unitsPerPixel: 0.1,
change: function(e,u){
synth.tuning = u.value;
}
});
$("#cutoff").dial({
numImages: 41,
imageWidth: 36,
min: 200.0,
max: 20000.0,
value: synth.cutoff,
unitsPerPixel: 100,
change: function(e,u){
synth.setcutoff(u.value);
}
});
$("#resonance").dial({
numImages: 41,
imageWidth: 36,
min: 0.0,
max: 1.0,
value: synth.resonance,
unitsPerPixel: 0.01,
change: function(e,u) {
synth.setresonance(u.value);
}
});
$("#envmod").dial({
numImages: 41,
imageWidth: 36,
min: 0.0,
max: 1.0,
value: synth.envmod,
unitsPerPixel: 0.01,
change: function(e,u) {
synth.setenvmod(u.value);
}
});
$("#decay").dial({
numImages: 41,
imageWidth: 36,
min: 100.0,
max: 2000.0,
value: synth.decay,
unitsPerPixel: 2,
change: function(e,u) {
synth.decay = u.value;
}
});
$("#accent").dial({
numImages: 41,
imageWidth: 36,
min: 0.0,
max: 1.0,
value: synth.accent,
unitsPerPixel: 0.01,
change: function(e,u) {
synth.accent = u.value;
}
});
$("#waveform").change(function(e) {
synth.waveform = $(this).attr("checked")?1:0;
}).attr("checked",synth.waveform==1?true:false);
$("#stepbutton").click(function(e) {
changestep((currentstep+1)%synth.pattern.length);
});
$("#backbutton").click(function(e) {
changestep((currentstep+synth.pattern.length-1)%synth.pattern.length);
});
$("#gatebutton").click(function(e) {
synth.pattern[currentstep][3]=!synth.pattern[currentstep][3];
$("#noteled").toggleClass("on",synth.pattern[currentstep][3]);
$("#restled").toggleClass("on",!synth.pattern[currentstep][3]);
});
$("#downbutton").click(function(e) {
synth.pattern[currentstep][4]=!synth.pattern[currentstep][4];
$("#downled").toggleClass("on",synth.pattern[currentstep][4]);
});
$("#upbutton").click(function(e) {
synth.pattern[currentstep][5]=!synth.pattern[currentstep][5];
$("#upled").toggleClass("on",synth.pattern[currentstep][5]);
});
$("#accentbutton").click(function(e) {
synth.pattern[currentstep][1]=!synth.pattern[currentstep][1];
$("#accentled").toggleClass("on",synth.pattern[currentstep][1]);
});
$("#slidebutton").click(function(e) {
synth.pattern[currentstep][2]=!synth.pattern[currentstep][2];
$("#slideled").toggleClass("on",synth.pattern[currentstep][2]);
});
$("#pitchmodebutton").click(function(e) {
pitchmode=!pitchmode;
$("#pitchmodeled").toggleClass("on",pitchmode);
});
$("#clearbutton").click(function(e) {
synth.pattern[currentstep][0]=40;
synth.pattern[currentstep][1]=false;
synth.pattern[currentstep][2]=false;
synth.pattern[currentstep][3]=false;
synth.pattern[currentstep][4]=false;
synth.pattern[currentstep][5]=false;
changestep(currentstep);
});
var changenote = function(e) {
var notes=["c","db","d","eb","e","f","gb","g","ab","a","bb","b","cc"];
if (pitchmode) {
synth.pattern[currentstep][0]=e.data.number+40;
changestep((currentstep+1)%synth.pattern.length);
} else {
$("#"+notes[synth.pattern[currentstep][0]-40]+"led").removeClass("on");
synth.pattern[currentstep][0]=e.data.number+40;
$("#"+notes[synth.pattern[currentstep][0]-40]+"led").addClass("on");
}
};
$("#cbutton").click({number:0},changenote);
$("#dbbutton").click({number:1},changenote);
$("#dbutton").click({number:2},changenote);
$("#ebbutton").click({number:3},changenote);
$("#ebutton").click({number:4},changenote);
$("#fbutton").click({number:5},changenote);
$("#gbbutton").click({number:6},changenote);
$("#gbutton").click({number:7},changenote);
$("#abbutton").click({number:8},changenote);
$("#abutton").click({number:9},changenote);
$("#bbbutton").click({number:10},changenote);
$("#bbutton").click({number:11},changenote);
$("#ccbutton").click({number:12},changenote);
$("#run").click(function(e){
// clearInterval(audiotimer);
synth.running=!synth.running;
});
$("#createpermalink a").click(function(e) {
$("#createpermalink").slideUp(200);
$.ajax({
data: {
data:JSON.stringify(synth.serialize())
},
dataType: "text",
error: function(xhr,stat,err) { alert("Oops! Something went horribly wrong: stat="+stat+" err="+err); },
success: function(data, status, xhr) {
$("#permalink .url").html("http://js303.com/s/"+data);
$("#permalink").slideDown(200);
},
type: "POST",
url: "/store"
});
});
changestep(currentstep);
// initialize wavetable
loadwavetable("/data/wavetable.png", function() {
// set up synth
var audio = new Audio();
if (typeof audio.mozSetup == 'function') {
audio.mozSetup(1,44100);
var apos=0;
var buf = new Float32Array(4410);
audiotimer = setInterval(function() {
var before = +new Date();
var b = buf, r = synth;
for (var i=0;i<4410;i++) {
b[i]=r.render();
}
apos+=audio.mozWriteAudio(b);
var after = +new Date();
$("#load").html((after-before)+"%");
},100);
} else {
// no audio data api available
}
});
});
})();