mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
Merge pull request #1972 from mzgoddard/sound-bank-over-sprite
Sound bank over sprite
This commit is contained in:
commit
33f4482127
5 changed files with 29 additions and 22 deletions
|
@ -8,10 +8,10 @@ const log = require('../util/log');
|
|||
* @property {Buffer} data - sound data will be written here once loaded.
|
||||
* @param {!Asset} soundAsset - the asset loaded from storage.
|
||||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||
* @param {Sprite} sprite - Scratch sprite to add sounds to.
|
||||
* @param {SoundBank} soundBank - Scratch Audio SoundBank to add sounds to.
|
||||
* @returns {!Promise} - a promise which will resolve to the sound when ready.
|
||||
*/
|
||||
const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
|
||||
const loadSoundFromAsset = function (sound, soundAsset, runtime, soundBank) {
|
||||
sound.assetId = soundAsset.assetId;
|
||||
if (!runtime.audioEngine) {
|
||||
log.error('No audio engine present; cannot load sound asset: ', sound.md5);
|
||||
|
@ -30,8 +30,8 @@ const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
|
|||
sound.rate = soundBuffer.sampleRate;
|
||||
sound.sampleCount = soundBuffer.length;
|
||||
|
||||
if (sprite.soundBank !== null) {
|
||||
sprite.soundBank.addSoundPlayer(soundPlayer);
|
||||
if (soundBank !== null) {
|
||||
soundBank.addSoundPlayer(soundPlayer);
|
||||
}
|
||||
|
||||
return sound;
|
||||
|
@ -44,10 +44,10 @@ const loadSoundFromAsset = function (sound, soundAsset, runtime, sprite) {
|
|||
* @property {string} md5 - the MD5 and extension of the sound to be loaded.
|
||||
* @property {Buffer} data - sound data will be written here once loaded.
|
||||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||
* @param {Sprite} sprite - Scratch sprite to add sounds to.
|
||||
* @param {SoundBank} soundBank - Scratch Audio SoundBank to add sounds to.
|
||||
* @returns {!Promise} - a promise which will resolve to the sound when ready.
|
||||
*/
|
||||
const loadSound = function (sound, runtime, sprite) {
|
||||
const loadSound = function (sound, runtime, soundBank) {
|
||||
if (!runtime.storage) {
|
||||
log.error('No storage module present; cannot load sound asset: ', sound.md5);
|
||||
return Promise.resolve(sound);
|
||||
|
@ -61,7 +61,7 @@ const loadSound = function (sound, runtime, sprite) {
|
|||
runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext)
|
||||
).then(soundAsset => {
|
||||
sound.asset = soundAsset;
|
||||
return loadSoundFromAsset(sound, soundAsset, runtime, sprite);
|
||||
return loadSoundFromAsset(sound, soundAsset, runtime, soundBank);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -399,9 +399,10 @@ const parseMonitorObject = (object, runtime, targets, extensions) => {
|
|||
* @param {!Runtime} runtime - Runtime object to load all structures into.
|
||||
* @param {boolean} topLevel - Whether this is the top-level object (stage).
|
||||
* @param {?object} zip - Optional zipped assets for local file import
|
||||
* @return {?{costumePromises:Array.<Promise>,soundPromises:Array.<Promise>,children:object}}
|
||||
* @return {?{costumePromises:Array.<Promise>,soundPromises:Array.<Promise>,soundBank:SoundBank,children:object}}
|
||||
* Object of arrays of promises and child objects for asset objects used in
|
||||
* Sprites. null for unsupported objects.
|
||||
* Sprites. As well as a SoundBank for the sound assets. null for unsupported
|
||||
* objects.
|
||||
*/
|
||||
const parseScratchAssets = function (object, runtime, topLevel, zip) {
|
||||
if (!object.hasOwnProperty('objName')) {
|
||||
|
@ -409,7 +410,12 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const assets = {costumePromises: [], soundPromises: [], children: []};
|
||||
const assets = {
|
||||
costumePromises: [],
|
||||
soundPromises: [],
|
||||
soundBank: runtime.audioEngine && runtime.audioEngine.createBank(),
|
||||
children: []
|
||||
};
|
||||
|
||||
// Costumes from JSON.
|
||||
const costumePromises = assets.costumePromises;
|
||||
|
@ -457,7 +463,7 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
|
|||
}
|
||||
}
|
||||
// Sounds from JSON
|
||||
const soundPromises = assets.soundPromises;
|
||||
const {soundBank, soundPromises} = assets;
|
||||
if (object.hasOwnProperty('sounds')) {
|
||||
for (let s = 0; s < object.sounds.length; s++) {
|
||||
const soundSource = object.sounds[s];
|
||||
|
@ -486,7 +492,10 @@ const parseScratchAssets = function (object, runtime, topLevel, zip) {
|
|||
// the file name of the sound should be the soundID (provided from the project.json)
|
||||
// followed by the file ext
|
||||
const assetFileName = `${soundSource.soundID}.${ext}`;
|
||||
soundPromises.push(deserializeSound(sound, runtime, zip, assetFileName).then(() => sound));
|
||||
soundPromises.push(
|
||||
deserializeSound(sound, runtime, zip, assetFileName)
|
||||
.then(() => loadSound(sound, runtime, soundBank))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,11 +555,7 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip,
|
|||
// Costumes from JSON.
|
||||
const costumePromises = assets.costumePromises;
|
||||
// Sounds from JSON
|
||||
const soundPromises = assets.soundPromises;
|
||||
for (let s = 0; s < soundPromises.length; s++) {
|
||||
soundPromises[s] = soundPromises[s]
|
||||
.then(sound => loadSound(sound, runtime, sprite));
|
||||
}
|
||||
const {soundBank, soundPromises} = assets;
|
||||
|
||||
// Create the first clone, and load its run-state from JSON.
|
||||
const target = sprite.createClone(topLevel ? StageLayering.BACKGROUND_LAYER : StageLayering.SPRITE_LAYER);
|
||||
|
@ -738,6 +743,8 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip,
|
|||
|
||||
Promise.all(soundPromises).then(sounds => {
|
||||
sprite.sounds = sounds;
|
||||
// Make sure if soundBank is undefined, sprite.soundBank is then null.
|
||||
sprite.soundBank = soundBank || null;
|
||||
});
|
||||
|
||||
// The stage will have child objects; recursively process them.
|
||||
|
|
|
@ -914,7 +914,7 @@ const parseScratchObject = function (object, runtime, extensions, zip) {
|
|||
// any translation that needs to happen will happen in the process
|
||||
// of building up the costume object into an sb3 format
|
||||
return deserializeSound(sound, runtime, zip)
|
||||
.then(() => loadSound(sound, runtime, sprite));
|
||||
.then(() => loadSound(sound, runtime, sprite.soundBank));
|
||||
// Only attempt to load the sound after the deserialization
|
||||
// process has been completed.
|
||||
});
|
||||
|
|
|
@ -153,7 +153,7 @@ class Sprite {
|
|||
newSprite.sounds = this.sounds.map(sound => {
|
||||
const newSound = Object.assign({}, sound);
|
||||
const soundAsset = sound.asset;
|
||||
assetPromises.push(loadSoundFromAsset(newSound, soundAsset, this.runtime, newSprite));
|
||||
assetPromises.push(loadSoundFromAsset(newSound, soundAsset, this.runtime, newSprite.soundBank));
|
||||
return newSound;
|
||||
});
|
||||
|
||||
|
|
|
@ -678,7 +678,7 @@ class VirtualMachine extends EventEmitter {
|
|||
duplicateSound (soundIndex) {
|
||||
const originalSound = this.editingTarget.getSounds()[soundIndex];
|
||||
const clone = Object.assign({}, originalSound);
|
||||
return loadSound(clone, this.runtime, this.editingTarget.sprite).then(() => {
|
||||
return loadSound(clone, this.runtime, this.editingTarget.sprite.soundBank).then(() => {
|
||||
this.editingTarget.addSound(clone, soundIndex + 1);
|
||||
this.emitTargetsUpdate();
|
||||
});
|
||||
|
@ -723,7 +723,7 @@ class VirtualMachine extends EventEmitter {
|
|||
const target = optTargetId ? this.runtime.getTargetById(optTargetId) :
|
||||
this.editingTarget;
|
||||
if (target) {
|
||||
return loadSound(soundObject, this.runtime, target.sprite).then(() => {
|
||||
return loadSound(soundObject, this.runtime, target.sprite.soundBank).then(() => {
|
||||
target.addSound(soundObject);
|
||||
this.emitTargetsUpdate();
|
||||
});
|
||||
|
@ -1250,7 +1250,7 @@ class VirtualMachine extends EventEmitter {
|
|||
const originalSound = this.editingTarget.getSounds()[soundIndex];
|
||||
const clone = Object.assign({}, originalSound);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
return loadSound(clone, this.runtime, target.sprite).then(() => {
|
||||
return loadSound(clone, this.runtime, target.sprite.soundBank).then(() => {
|
||||
if (target) {
|
||||
target.addSound(clone);
|
||||
this.emitTargetsUpdate();
|
||||
|
|
Loading…
Reference in a new issue