New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

scratch-audio

Package Overview
Dependencies
Maintainers
1
Versions
481
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scratch-audio - npm Package Compare versions

Comparing version

to
0.1.0-prerelease.1485809602

2

package.json
{
"name": "scratch-audio",
"version": "0.1.0-prerelease.1485794611",
"version": "0.1.0-prerelease.1485809602",
"description": "audio engine for scratch 3.0",

@@ -5,0 +5,0 @@ "main": "dist.js",

@@ -59,3 +59,3 @@ /*

// todo: this line is the only place Tone is used here, should be possible to remove
// this line is the only place Tone is used here, should be possible to remove
var buffer = Tone.context.createBuffer(1, samples.length, this.samplesPerSecond);

@@ -62,0 +62,0 @@

@@ -11,3 +11,2 @@ /*

this.value = 0;
this.ratio = 1;

@@ -19,3 +18,2 @@ this.tone = new Tone();

this.value = val;
this.ratio = this.getRatio(this.value);
this.updatePlayers(players);

@@ -28,21 +26,17 @@ };

PitchEffect.prototype.getRatio = function (val) {
return this.tone.intervalToFrequencyRatio(val / 10);
PitchEffect.prototype.getRatio = function () {
return this.tone.intervalToFrequencyRatio(this.value / 10);
};
PitchEffect.prototype.updatePlayer = function (player) {
player.setPlaybackRate(this.ratio);
};
PitchEffect.prototype.updatePlayers = function (players) {
if (!players) return;
for (var md5 in players) {
this.updatePlayer(players[md5]);
var ratio = this.getRatio();
for (var i=0; i<players.length; i++) {
players[i].setPlaybackRate(ratio);
}
};
module.exports = PitchEffect;

@@ -20,4 +20,3 @@ var log = require('./log');

The Scratch runtime has a single audio engine that handles global audio properties and effects,
loads all the audio buffers for sounds belonging to sprites, and creates a single instrument player
and a drum player, used by all play note and play drum blocks
and creates the instrument player and a drum player, used by all play note and play drum blocks

@@ -43,2 +42,4 @@ */

this.currentTempo = 60;
this.minTempo = 10;
this.maxTempo = 1000;

@@ -52,57 +53,6 @@ // instrument player for play note blocks

this.numDrums = this.drumPlayer.drumSounds.length;
// a map of md5s to audio buffers, holding sounds for all sprites
this.audioBuffers = {};
}
AudioEngine.prototype.loadSounds = function (sounds) {
// most sounds decode natively, but for adpcm sounds we use our own decoder
var storedContext = this;
for (var i=0; i<sounds.length; i++) {
var md5 = sounds[i].md5;
var buffer = new Tone.Buffer();
this.audioBuffers[md5] = buffer;
if (sounds[i].format == 'squeak') {
log.warn('unable to load sound in squeak format');
continue;
}
if (sounds[i].format == 'adpcm') {
log.warn('loading sound in adpcm format');
// create a closure to store the sound md5, to use when the
// decoder completes and resolves the promise
(function () {
var storedMd5 = sounds[i].md5;
var loader = new ADPCMSoundLoader();
loader.load(sounds[i].fileUrl).then(function (audioBuffer) {
storedContext.audioBuffers[storedMd5] = new Tone.Buffer(audioBuffer);
});
}());
} else {
this.audioBuffers[md5] = new Tone.Buffer(sounds[i].fileUrl);
}
}
};
AudioEngine.prototype.playNoteForBeatsWithInst = function (note, beats, inst) {
var sec = this.beatsToSec(beats);
this.instrumentPlayer.playNoteForSecWithInst(note, sec, inst);
return this.waitForBeats(beats);
};
AudioEngine.prototype.beatsToSec = function (beats) {
return (60 / this.currentTempo) * beats;
};
AudioEngine.prototype.waitForBeats = function (beats) {
var storedContext = this;
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, storedContext.beatsToSec(beats) * 1000);
});
};
AudioEngine.prototype.setTempo = function (value) {
// var newTempo = this._clamp(value, this.minTempo, this.maxTempo);
this.currentTempo = value;

@@ -121,5 +71,6 @@ };

Each sprite or clone has an audio player
the audio player handles sound playback and the sprite-specific audio effects
pitch and pan, and volume
Each sprite has an audio player
Clones receive a reference to their parent's audio player
the audio player currently handles sound loading and playback, sprite-specific effects
(pitch and pan) and volume

@@ -145,38 +96,84 @@ */

// sound players that are currently playing, indexed by the sound's md5
this.activeSoundPlayers = Object.create({});
this.effectNames = ['PITCH', 'PAN', 'ECHO', 'REVERB', 'FUZZ', 'ROBOT'];
this.currentVolume = 100;
this.currentInstrument = 0;
}
AudioPlayer.prototype.playSound = function (md5) {
// if this sprite or clone is already playing this sound, stop it first
// (this is not working, not sure why)
if (this.activeSoundPlayers[md5]) {
this.activeSoundPlayers[md5].stop();
AudioPlayer.prototype.loadSounds = function (sounds) {
this.soundPlayers = [];
// create a set of empty sound player objects
// the sound buffers will be added asynchronously as they load
for (var i=0; i<sounds.length; i++){
this.soundPlayers[i] = new SoundPlayer(this.effectsNode);
}
// create a new soundplayer to play the sound
var player = new SoundPlayer();
player.setBuffer(this.audioEngine.audioBuffers[md5]);
player.connect(this.effectsNode);
this.pitchEffect.updatePlayer(player);
player.start();
// load the sounds
// most sounds decode natively, but for adpcm sounds we use our own decoder
var storedContext = this;
for (var index=0; index<sounds.length; index++) {
if (sounds[index].format == 'squeak') {
log.warn('unable to load sound in squeak format');
continue;
}
if (sounds[index].format == 'adpcm') {
log.warn('loading sound in adpcm format');
// create a closure to store the sound index, to use when the
// decoder completes and resolves the promise
(function () {
var storedIndex = index;
var loader = new ADPCMSoundLoader();
loader.load(sounds[storedIndex].fileUrl).then(function (audioBuffer) {
storedContext.soundPlayers[storedIndex].setBuffer(new Tone.Buffer(audioBuffer));
});
}());
} else {
this.soundPlayers[index].setBuffer(new Tone.Buffer(sounds[index].fileUrl));
}
}
// add it to the list of active sound players
this.activeSoundPlayers[md5] = player;
};
// when the sound completes, remove it from the list of active sound players
return player.finished().then(() => {
delete this.activeSoundPlayers[md5];
AudioPlayer.prototype.playSound = function (index) {
if (!this.soundPlayers[index]) return;
this.soundPlayers[index].start();
var storedContext = this;
return new Promise(function (resolve) {
storedContext.soundPlayers[index].onEnded(resolve);
});
};
AudioPlayer.prototype.playNoteForBeats = function (note, beats) {
var sec = this.beatsToSec(beats);
this.audioEngine.instrumentPlayer.playNoteForSecWithInst(note, sec, this.currentInstrument);
return this.waitForBeats(beats);
};
AudioPlayer.prototype.playDrumForBeats = function (drum, beats) {
this.audioEngine.drumPlayer.play(drum, this.effectsNode);
return this.audioEngine.waitForBeats(beats);
return this.waitForBeats(beats);
};
AudioPlayer.prototype.waitForBeats = function (beats) {
var storedContext = this;
return new Promise(function (resolve) {
setTimeout(function () {
resolve();
}, storedContext.beatsToSec(beats) * 1000);
});
};
AudioPlayer.prototype.beatsToSec = function (beats) {
return (60 / this.audioEngine.currentTempo) * beats;
};
AudioPlayer.prototype.stopAllSounds = function () {
// stop all active sound players
for (var md5 in this.activeSoundPlayers) {
this.activeSoundPlayers[md5].stop();
// stop all sound players
for (var i=0; i<this.soundPlayers.length; i++) {
this.soundPlayers[i].stop();
}

@@ -189,6 +186,3 @@

this.audioEngine.drumPlayer.stopAll();
};
AudioPlayer.prototype.setPitchEffect = function (value) {
this.pitchEffect.set(value, this.activeSoundPlayers);
};

@@ -198,18 +192,18 @@

switch (effect) {
case 'pitch':
this.pitchEffect.set(value, this.activeSoundPlayers);
case 'PITCH':
this.pitchEffect.set(value, this.soundPlayers);
break;
case 'pan':
case 'PAN':
this.panEffect.set(value);
break;
case 'echo':
case 'ECHO':
this.audioEngine.echoEffect.set(value);
break;
case 'reverb':
case 'REVERB':
this.audioEngine.reverbEffect.set(value);
break;
case 'fuzz' :
case 'FUZZ' :
this.audioEngine.fuzzEffect.set(value);
break;
case 'robot' :
case 'ROBOT' :
this.audioEngine.roboticEffect.set(value);

@@ -220,5 +214,29 @@ break;

AudioPlayer.prototype.changeEffect = function (effect, value) {
switch (effect) {
case 'PITCH':
this.pitchEffect.changeBy(value, this.soundPlayers);
break;
case 'PAN':
this.panEffect.changeBy(value);
break;
case 'ECHO':
this.audioEngine.echoEffect.changeBy(value);
break;
case 'REVERB':
this.audioEngine.reverbEffect.changeBy(value);
break;
case 'FUZZ' :
this.audioEngine.fuzzEffect.changeBy(value);
break;
case 'ROBOT' :
this.audioEngine.roboticEffect.changeBy(value);
break;
}
};
AudioPlayer.prototype.clearEffects = function () {
this.panEffect.set(0);
this.pitchEffect.set(0, this.activeSoundPlayers);
this.pitchEffect.set(0, this.soundPlayers);
this.effectsNode.gain.value = 1;

@@ -232,2 +250,7 @@

AudioPlayer.prototype.setInstrument = function (instrumentNum) {
this.currentInstrument = instrumentNum;
return this.audioEngine.instrumentPlayer.loadInstrument(this.currentInstrument);
};
AudioPlayer.prototype.setVolume = function (value) {

@@ -234,0 +257,0 @@ this.currentVolume = this._clamp(value, 0, 100);

var Tone = require('tone');
var log = require('./log');
function SoundPlayer () {
this.outputNode;
function SoundPlayer (outputNode) {
this.outputNode = outputNode;
this.buffer; // a Tone.Buffer
this.bufferSource;
this.playbackRate = 1;
this.isPlaying = false;
}
SoundPlayer.prototype.connect = function (node) {
this.outputNode = node;
};

@@ -26,3 +24,3 @@ SoundPlayer.prototype.setBuffer = function (buffer) {

SoundPlayer.prototype.stop = function () {
if (this.bufferSource) {
if (this.isPlaying){
this.bufferSource.stop();

@@ -38,2 +36,4 @@ }

this.stop();
this.bufferSource = new Tone.BufferSource(this.buffer.get());

@@ -43,13 +43,12 @@ this.bufferSource.playbackRate.value = this.playbackRate;

this.bufferSource.start();
this.isPlaying = true;
};
SoundPlayer.prototype.finished = function () {
var storedContext = this;
return new Promise(function (resolve) {
storedContext.bufferSource.onended = function () {
resolve();
};
});
SoundPlayer.prototype.onEnded = function (callback) {
this.bufferSource.onended = function () {
this.isPlaying = false;
callback();
};
};
module.exports = SoundPlayer;

Sorry, the diff of this file is too big to display