blue.js/libs/blueaudio.js

88 lines
3.6 KiB
JavaScript

/////////////////////// BlueAudio 1.0.4 \\\\\\\\\\\\\\\\\\\\\\\\\\
// This requires BlueCore in order to run and assumes it is \\
// already loaded. It will not work without BlueCore loaded \\
// first. \\
//////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
function getFrequency (note, octave) {
// octaves double value
// half steps are calculated using fn = f0*(2^(1/12))^n
var base = 16.35; // bottom c
var a = Math.pow(2,1/12); // Defining a
// Check our inputs for sanity
if ("number" != typeof note) { note = 1; }
if ("number" != typeof octave) { octave = 4; }
if (note < 0) { note = 0;}
if (note > 11) { note = 11; }
if (octave < 0) { octave = 0; }
if (octave > 8) { octave = 8; }
return (base*Math.pow(a,note))*Math.pow(2,octave);
}
function parseNote (string) {
if ("string" != typeof string) { string = "4c1/4"; }
var noteReg = new RegExp(/^([1-8])([a-g][nb#]?)(\d)\/(\d{1,2})/i);
var noteArray = string.match(noteReg);
if (noteArray) { if (noteArray.length == 5) {
var noteTranslationObject = {"cb":11,"cn":0,"c":0,"c#":1,"db":1,"dn":2,"d":2,"d#":3,"eb":3,"en":4,"e":4,"e#":5,"fb":4,"fn":5,"f":5,"f#":6,"gb":6,"gn":7,"g":7,"g#":8,"ab":8,"an":9,"a":9,"a#":10,"bb":10,"bn":11,"b":11,"b#":0};
var octave = noteArray[1]-0;
var length = (noteArray[3]/noteArray[4]);
var step = noteTranslationObject[noteArray[2]];
if ("cb" == noteArray[2]) { octave--; }
if ("b#" == noteArray[2]) { octave++; }
return {"note":step,"octave":octave,"length":length};
} else {
console.log("bad note: "+noteArray.join(" "));
return {};
}} else {
console.log("bad note");
return {};
}
}
function parseSequence (string) {
if ("string" != typeof string) { string = "4c1/4;"; }
var notes = string.split(";");
var sequence = [];
notes.forEach( function (note) {
sequence.push( parseNote(note) );
});
return sequence;
}
function playNote (soundObject, note, octave, length, wave, delay) {
if ("string" != typeof wave) { wave = "sine"; }
if ("number" != typeof length) { length = 1; }
if ("number" != typeof octave) { octave = 4; }
if ("number" != typeof note) { note = 0; }
if ("object" != typeof soundObject) { soundObject = new AudioContext(); }
if ("number" != typeof delay) { delay = 0; }
var waveform = soundObject.createOscillator();
var gain = soundObject.createGain();
waveform.connect(gain);
gain.connect(soundObject.destination);
waveform.type = wave;
waveform.frequency.setValueAtTime(getFrequency(note,octave), 0);
gain.gain.setValueAtTime(1, soundObject.currentTime+delay);
waveform.start(soundObject.currentTime+delay);
gain.gain.exponentialRampToValueAtTime(0.00001,soundObject.currentTime+length+delay);
waveform.stop(soundObject.currentTime+(length*1.5)+delay);
}
function playSequence (soundObject, sequenceArray, defaultWave, tempo) {
if ("object" != typeof soundObject) { soundObject = new AudioContext(); }
if ("string" != typeof defaultWave) { defaultWave = "sine"; }
if ("sine" != defaultWave && "square" != defaultWave && "triangle" != defaultWave && "sawtooth" != defaultWave) { defaultWave = "sine"; }
if ("number" != typeof tempo) { tempo = 60; }
if (0 >= tempo) { tempo = 1; }
if ("object" != typeof sequenceArray) { sequenceArray = [{"note":0,"octave":4,"length":1,"type":"sine"}]; }
var timing = 0;
sequenceArray.forEach( function (thisNote) {
var adjustedLength = (thisNote.length*(60/tempo))*4;
if ("undefined" == typeof thisNote.type) { thisNote.type = defaultWave; }
playNote(soundObject, thisNote.note, thisNote.octave, adjustedLength, thisNote.type, timing);
timing += adjustedLength/4;
});
}