diff --git a/AudioEngine.js b/AudioEngine.js index ee02a013..8b5aa036 100644 --- a/AudioEngine.js +++ b/AudioEngine.js @@ -27,7 +27,7 @@ function AudioEngine () { // sound files - var soundFileNames = ['meow','boing','this_is_a_test','who_put_the_bomp','cave','drip_drop','drum_machine','eggs','zoop']; + var soundFileNames = ['meow','boing','cave','drip_drop','drum_machine','eggs','zoop']; this.soundSamplers = this._loadSoundFiles(soundFileNames); } @@ -35,6 +35,10 @@ AudioEngine.prototype.playSound = function (soundNum) { this.soundSamplers[soundNum].triggerAttack(); }; +AudioEngine.prototype.getSoundDuration = function (soundNum) { + return this.soundSamplers[soundNum].player.buffer.duration; +}; + AudioEngine.prototype.playNoteForBeats = function(note, beats) { var freq = this._midiToFreq(note); this.synth.triggerAttackRelease(freq, beats); @@ -57,6 +61,50 @@ AudioEngine.prototype.stopAllSounds = function() { } }; +AudioEngine.prototype.setEffect = function(effect, value) { + switch (effect) { + case 'ECHO': + this.delay.wet.value = (value / 100) / 2; // max 50% wet (need dry signal too) + break; + case 'PAN': + this.panner.pan.value = value / 100; + break; + case 'REVERB': + this.reverb.wet.value = value / 100; + break; + case 'PITCH': + this.pitchShift.pitch = value / 20; // arbitrary scaling of 20 per semitone, for now... default 100 is a perfect fourth + break; + } +} + +AudioEngine.prototype.changeEffect = function(effect, value) { + switch (effect) { + case 'ECHO': + this.delay.wet.value += (value / 100) / 2; // max 50% wet (need dry signal too) + this.delay.wet.value = this._clamp(this.delay.wet.value, 0, 0.5); + break; + case 'PAN': + this.panner.pan.value += value / 100; + this.panner.pan.value = this._clamp(this.panner.pan.value, -1, 1); + break; + case 'REVERB': + this.reverb.wet.value += value / 100; + this.reverb.wet.value = this._clamp(this.reverb.wet.value, 0, 1); + break; + case 'PITCH': + this.pitchShift.pitch += value / 20; + break; + } +} + +AudioEngine.prototype.clearEffects = function() { + this.delay.wet.value = 0; + this.panner.pan.value = 0; + this.reverb.wet.value = 0; + this.pitchShift.pitch = 0; +} + AudioEngine.prototype._loadSoundFiles = function(filenames) { var samplers = []; diff --git a/src/blocks/scratch3_sound.js b/src/blocks/scratch3_sound.js index a6f4c04c..5eb5b33f 100644 --- a/src/blocks/scratch3_sound.js +++ b/src/blocks/scratch3_sound.js @@ -16,7 +16,7 @@ function Scratch3SoundBlocks(runtime) { Scratch3SoundBlocks.prototype.getPrimitives = function() { return { 'sound_playsound': this.playSound, - // 'sound_playsoundandwait': this.playSoundAndWait, + 'sound_playuntildone': this.playSoundAndWait, 'sound_stopallsounds': this.stopAllSounds, 'sound_playnoteforbeats': this.playNoteForBeats, 'sound_playdrumforbeats': this.playDrumForBeats, @@ -30,15 +30,25 @@ Scratch3SoundBlocks.prototype.getPrimitives = function() { }; Scratch3SoundBlocks.prototype.playSound = function (args, util) { - util.target.playSound(args.SOUND_NUM); + window.audioEngine.playSound(args.SOUND_NUM); +}; + +Scratch3SoundBlocks.prototype.playSoundAndWait = function (args, util) { + window.audioEngine.playSound(args.SOUND_NUM); + var duration = window.audioEngine.getSoundDuration(args.SOUND_NUM); + return new Promise(function(resolve) { + setTimeout(function() { + resolve(); + }, 1000*duration); + }); }; Scratch3SoundBlocks.prototype.stopAllSounds = function (args, util) { - util.target.stopAllSounds(); + window.audioEngine.stopAllSounds(); }; Scratch3SoundBlocks.prototype.playNoteForBeats = function (args, util) { - util.target.playNoteForBeats(args.NOTE, args.BEATS); + window.audioEngine.playNoteForBeats(args.NOTE, args.BEATS); return new Promise(function(resolve) { setTimeout(function() { resolve(); @@ -47,7 +57,7 @@ Scratch3SoundBlocks.prototype.playNoteForBeats = function (args, util) { }; Scratch3SoundBlocks.prototype.playDrumForBeats = function (args, util) { - util.target.playDrumForBeats(args.DRUMTYPE, args.BEATS); + window.audioEngine.playDrumForBeats(args.DRUMTYPE, args.BEATS); return new Promise(function(resolve) { setTimeout(function() { resolve(); @@ -56,12 +66,15 @@ Scratch3SoundBlocks.prototype.playDrumForBeats = function (args, util) { }; Scratch3SoundBlocks.prototype.setEffect = function (args, util) { + window.audioEngine.setEffect(args.EFFECT, args.VALUE); }; Scratch3SoundBlocks.prototype.changeEffect = function (args, util) { + window.audioEngine.changeEffect(args.EFFECT, args.VALUE); }; Scratch3SoundBlocks.prototype.clearEffects = function (args, util) { + window.audioEngine.clearEffects(); }; Scratch3SoundBlocks.prototype.soundsMenu = function (args, util) { diff --git a/src/index.js b/src/index.js index aafed8e2..a51bae13 100644 --- a/src/index.js +++ b/src/index.js @@ -224,10 +224,6 @@ VirtualMachine.prototype.emitWorkspaceUpdate = function () { 'xml': this.editingTarget.blocks.toXML() }); }; -<<<<<<< HEAD - -======= ->>>>>>> LLK/develop /** * Export and bind to `window` */ diff --git a/src/sprites/clone.js b/src/sprites/clone.js index 185a0e4f..d6a2072e 100644 --- a/src/sprites/clone.js +++ b/src/sprites/clone.js @@ -32,8 +32,6 @@ function Clone(sprite) { this.initDrawable(); - // audio engine - this.audioWorker = self.audioWorker; } util.inherits(Clone, Target); @@ -277,24 +275,6 @@ Clone.prototype.getName = function () { return this.sprite.name; }; -// Audio - -Clone.prototype.playSound = function (soundNum) { - window.audioEngine.playSound(soundNum); -} - -Clone.prototype.stopAllSounds = function () { - window.audioEngine.stopAllSounds(); -} - -Clone.prototype.playNoteForBeats = function (note,beats) { - window.audioEngine.playNoteForBeats(note, beats); -} - -Clone.prototype.playDrumForBeats = function (drumNum,beats) { - window.audioEngine.playDrumForBeats(drumNum, beats); -} - /** * Return whether the clone is touching a color. * @param {Array.} rgb [r,g,b], values between 0-255.