scratch-audioengine
Advanced tools
Comparing version 0.1.0-prerelease.1476480694 to 0.1.0-prerelease.1476897336
{ | ||
"name": "scratch-audioengine", | ||
"version": "0.1.0-prerelease.1476480694", | ||
"version": "0.1.0-prerelease.1476897336", | ||
"description": "audio engine for scratch 3.0", | ||
@@ -5,0 +5,0 @@ "main": "dist.js", |
104
src/index.js
@@ -11,2 +11,3 @@ var Tone = require('tone'); | ||
// effects setup | ||
// each effect has a single parameter controlled by the effects block | ||
@@ -16,6 +17,12 @@ this.delay = new Tone.FeedbackDelay(0.25, 0.5); | ||
this.reverb = new Tone.Freeverb(); | ||
this.pitchShiftRatio; | ||
// reset effects to their default parameters | ||
this.clearEffects(); | ||
Tone.Master.chain(this.delay, this.panner, this.reverb); | ||
// the effects are chained to an effects node for this clone, then to the master output | ||
// so audio is sent from each sampler or instrument, through the effects in order, then out | ||
// note that the pitch effect works differently - it sets the playback rate for each sampler | ||
this.effectsNode = new Tone.Gain(); | ||
this.effectsNode.chain(this.delay, this.panner, this.reverb, Tone.Master); | ||
@@ -40,8 +47,13 @@ // drum sounds | ||
Soundfont.instrument(Tone.context, this.instrumentNames[0]).then( | ||
function (inst) { | ||
this.instrument = inst; | ||
this.instrument.connect(Tone.Master); | ||
}.bind(this) | ||
); | ||
this.setInstrument(0); | ||
// theremin setup | ||
this.theremin = new Tone.Synth(); | ||
this.portamentoTime = 0.25; | ||
this.theremin.portamento = this.portamentoTime; | ||
this.thereminVibrato = new Tone.Vibrato(4, 0.5); | ||
this.theremin.chain(this.thereminVibrato, this.effectsNode); | ||
this.thereminTimeout; | ||
this.thereminIsPlaying = false; | ||
} | ||
@@ -52,31 +64,16 @@ | ||
var url = sounds[i].fileUrl; | ||
var sampler = new Tone.Sampler(url, function () { | ||
this.soundSamplers[url] = sampler; | ||
}.bind(this)).toMaster(); | ||
var sampler = new Tone.Sampler(url); | ||
sampler.connect(this.effectsNode); | ||
this.soundSamplers.push(sampler); | ||
} | ||
}; | ||
AudioEngine.prototype.playSound = function (soundNum) { | ||
this.soundSamplers[soundNum].triggerAttack(); | ||
}; | ||
AudioEngine.prototype.playSound = function (index) { | ||
this.soundSamplers[index].triggerAttack(); | ||
this.soundSamplers[index].player.playbackRate = 1 + this.pitchShiftRatio; | ||
AudioEngine.prototype.playSoundFromUrl = function (url) { | ||
if (url) { | ||
// if we've loaded it already, play it | ||
if (this.soundSamplers[url]) { | ||
// this.soundSamplers[url].triggerAttack(); | ||
this.soundSamplers[url].player.start(); | ||
} else { | ||
// else load, play, and store it | ||
// this results in a delay the first time you play the sound | ||
var sampler = new Tone.Sampler(url, function () { | ||
sampler.triggerAttack(); | ||
this.soundSamplers[url] = sampler; | ||
}.bind(this)).toMaster(); | ||
} | ||
} | ||
}; | ||
AudioEngine.prototype.getSoundDuration = function (url) { | ||
return this.soundSamplers[url].player.buffer.duration; | ||
AudioEngine.prototype.getSoundDuration = function (index) { | ||
return this.soundSamplers[index].player.buffer.duration; | ||
}; | ||
@@ -90,2 +87,31 @@ | ||
AudioEngine.prototype.playThereminForBeats = function (note, beats) { | ||
// if the theremin is playing | ||
// set frequency | ||
// else | ||
// trigger attack | ||
// create a timeout for slightly longer than the duration of the block | ||
// that releases the theremin - so we can slide continuously between | ||
// successive notes without releasing and attacking | ||
var freq = this._midiToFreq(note); | ||
if (this.thereminIsPlaying) { | ||
this.theremin.frequency.rampTo(freq, this.portamentoTime); | ||
} else { | ||
this.theremin.triggerAttack(freq); | ||
this.thereminIsPlaying = true; | ||
} | ||
clearTimeout(this.thereminTimeout); | ||
this.thereminTimeout = setTimeout(function () { | ||
this.theremin.triggerRelease(); | ||
this.thereminIsPlaying = false; | ||
}.bind(this), (1000 * beats) + 100); | ||
}; | ||
AudioEngine.prototype._midiToFreq = function (midiNote) { | ||
var freq = this.tone.intervalToFrequencyRatio(midiNote - 60) * 261.63; // 60 is C4 | ||
return freq; | ||
}; | ||
AudioEngine.prototype.playDrumForBeats = function (drumNum) { | ||
@@ -140,3 +166,3 @@ this.drumSamplers[drumNum].triggerAttack(); | ||
case 'PITCH': | ||
// this.pitchShift.pitch += value / 20; | ||
this._setPitchShift(this.pitchShiftRatio + (value / 20)); | ||
break; | ||
@@ -147,7 +173,17 @@ } | ||
AudioEngine.prototype._setPitchShift = function (value) { | ||
this.pitchShiftRatio = value; | ||
for (var i in this.soundSamplers) { | ||
this.soundSamplers[i].player.playbackRate = 1 + value; | ||
this.soundSamplers[i].player.playbackRate = 1 + this.pitchShiftRatio; | ||
} | ||
}; | ||
AudioEngine.prototype.setInstrument = function (instrumentNum) { | ||
return Soundfont.instrument(Tone.context, this.instrumentNames[instrumentNum]).then( | ||
function (inst) { | ||
this.instrument = inst; | ||
this.instrument.connect(this.effectsNode); | ||
}.bind(this) | ||
); | ||
}; | ||
AudioEngine.prototype.clearEffects = function () { | ||
@@ -160,6 +196,2 @@ this.delay.wet.value = 0; | ||
// AudioEngine.prototype.loadSoundFromUrl = function(url) { | ||
// }; | ||
AudioEngine.prototype._clamp = function (input, min, max) { | ||
@@ -166,0 +198,0 @@ return Math.min(Math.max(input, min), max); |
Sorry, the diff of this file is too big to display
806597
23435