mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
Merge pull request #936 from ericrosenbaum/feature/require-music-assets
Feature/require music assets
This commit is contained in:
commit
ca08cd69e9
4 changed files with 123 additions and 37 deletions
|
@ -33,12 +33,14 @@
|
|||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^7.0.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"buffer-loader": "0.0.1",
|
||||
"copy-webpack-plugin": "4.2.1",
|
||||
"decode-html": "2.0.0",
|
||||
"escape-html": "1.0.3",
|
||||
"eslint": "^4.5.0",
|
||||
"eslint-config-scratch": "^5.0.0",
|
||||
"expose-loader": "0.7.4",
|
||||
"file-loader": "^1.1.6",
|
||||
"format-message": "5.2.1",
|
||||
"format-message-cli": "5.2.1",
|
||||
"gh-pages": "^1.1.0",
|
||||
|
|
|
@ -5,6 +5,17 @@ const Cast = require('../../util/cast');
|
|||
const MathUtil = require('../../util/math-util');
|
||||
const Timer = require('../../util/timer');
|
||||
|
||||
/**
|
||||
* The instrument and drum sounds, loaded as static assets.
|
||||
* @type {object}
|
||||
*/
|
||||
let assetData = {};
|
||||
try {
|
||||
assetData = require('./manifest');
|
||||
} catch (e) {
|
||||
// Non-webpack environment, don't worry about assets.
|
||||
}
|
||||
|
||||
/**
|
||||
* Icon svg to be displayed at the left edge of each extension block, encoded as a data URI.
|
||||
* @type {string}
|
||||
|
@ -73,21 +84,20 @@ class Scratch3MusicBlocks {
|
|||
}
|
||||
|
||||
/**
|
||||
* Download and decode the full set of drum and instrument sounds, and
|
||||
* store the audio buffers in arrays.
|
||||
* Decode the full set of drum and instrument sounds, and store the audio buffers in arrays.
|
||||
*/
|
||||
_loadAllSounds () {
|
||||
const loadingPromises = [];
|
||||
this.DRUM_INFO.forEach((drumInfo, index) => {
|
||||
const fileName = `drums/${drumInfo.fileName}`;
|
||||
const promise = this._loadSound(fileName, index, this._drumBuffers);
|
||||
const filePath = `drums/${drumInfo.fileName}`;
|
||||
const promise = this._storeSound(filePath, index, this._drumBuffers);
|
||||
loadingPromises.push(promise);
|
||||
});
|
||||
this.INSTRUMENT_INFO.forEach((instrumentInfo, instrumentIndex) => {
|
||||
this._instrumentBufferArrays[instrumentIndex] = [];
|
||||
instrumentInfo.samples.forEach((sample, noteIndex) => {
|
||||
const fileName = `instruments/${instrumentInfo.dirName}/${sample}`;
|
||||
const promise = this._loadSound(fileName, noteIndex, this._instrumentBufferArrays[instrumentIndex]);
|
||||
const filePath = `instruments/${instrumentInfo.dirName}/${sample}`;
|
||||
const promise = this._storeSound(filePath, noteIndex, this._instrumentBufferArrays[instrumentIndex]);
|
||||
loadingPromises.push(promise);
|
||||
});
|
||||
});
|
||||
|
@ -97,35 +107,48 @@ class Scratch3MusicBlocks {
|
|||
}
|
||||
|
||||
/**
|
||||
* Download and decode a sound, and store the buffer in an array.
|
||||
* @param {string} fileName - the audio file name.
|
||||
* Decode a sound and store the buffer in an array.
|
||||
* @param {string} filePath - the audio file name.
|
||||
* @param {number} index - the index at which to store the audio buffer.
|
||||
* @param {array} bufferArray - the array of buffers in which to store it.
|
||||
* @return {Promise} - a promise which will resolve once the sound has loaded.
|
||||
* @return {Promise} - a promise which will resolve once the sound has been stored.
|
||||
*/
|
||||
_loadSound (fileName, index, bufferArray) {
|
||||
if (!this.runtime.storage) return;
|
||||
_storeSound (filePath, index, bufferArray) {
|
||||
const fullPath = `${filePath}.mp3`;
|
||||
|
||||
if (!assetData[fullPath]) return;
|
||||
|
||||
// The sound buffer has already been downloaded via the manifest file required above.
|
||||
const soundBuffer = assetData[fullPath].buffer;
|
||||
|
||||
return this._decodeSound(soundBuffer).then(buffer => {
|
||||
bufferArray[index] = buffer;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a sound and return a promise with the audio buffer.
|
||||
* @param {ArrayBuffer} soundBuffer - a buffer containing the encoded audio.
|
||||
* @return {Promise} - a promise which will resolve once the sound has decoded.
|
||||
*/
|
||||
_decodeSound (soundBuffer) {
|
||||
if (!this.runtime.audioEngine) return;
|
||||
if (!this.runtime.audioEngine.audioContext) return;
|
||||
return this.runtime.storage.load(this.runtime.storage.AssetType.Sound, fileName, 'mp3')
|
||||
.then(soundAsset => {
|
||||
const context = this.runtime.audioEngine.audioContext;
|
||||
// Check for newer promise-based API
|
||||
if (context.decodeAudioData.length === 1) {
|
||||
return context.decodeAudioData(soundAsset.data.buffer);
|
||||
} else { // eslint-disable-line no-else-return
|
||||
// Fall back to callback API
|
||||
return new Promise((resolve, reject) =>
|
||||
context.decodeAudioData(soundAsset.data.buffer,
|
||||
buffer => resolve(buffer),
|
||||
error => reject(error)
|
||||
)
|
||||
);
|
||||
}
|
||||
})
|
||||
.then(buffer => {
|
||||
bufferArray[index] = buffer;
|
||||
});
|
||||
|
||||
const context = this.runtime.audioEngine.audioContext;
|
||||
|
||||
// Check for newer promise-based API
|
||||
if (context.decodeAudioData.length === 1) {
|
||||
return context.decodeAudioData(soundBuffer);
|
||||
} else { // eslint-disable-line no-else-return
|
||||
// Fall back to callback API
|
||||
return new Promise((resolve, reject) =>
|
||||
context.decodeAudioData(soundBuffer,
|
||||
buffer => resolve(buffer),
|
||||
error => reject(error)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
63
src/extensions/scratch3_music/manifest.js
Normal file
63
src/extensions/scratch3_music/manifest.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
module.exports = {
|
||||
'drums/1-snare.mp3': require('!buffer-loader!./assets/drums/1-snare.mp3'),
|
||||
'drums/2-bass-drum.mp3': require('!buffer-loader!./assets/drums/2-bass-drum.mp3'),
|
||||
'drums/3-side-stick.mp3': require('!buffer-loader!./assets/drums/3-side-stick.mp3'),
|
||||
'drums/4-crash-cymbal.mp3': require('!buffer-loader!./assets/drums/4-crash-cymbal.mp3'),
|
||||
'drums/5-open-hi-hat.mp3': require('!buffer-loader!./assets/drums/5-open-hi-hat.mp3'),
|
||||
'drums/6-closed-hi-hat.mp3': require('!buffer-loader!./assets/drums/6-closed-hi-hat.mp3'),
|
||||
'drums/7-tambourine.mp3': require('!buffer-loader!./assets/drums/7-tambourine.mp3'),
|
||||
'drums/8-hand-clap.mp3': require('!buffer-loader!./assets/drums/8-hand-clap.mp3'),
|
||||
'drums/9-claves.mp3': require('!buffer-loader!./assets/drums/9-claves.mp3'),
|
||||
'drums/10-wood-block.mp3': require('!buffer-loader!./assets/drums/10-wood-block.mp3'),
|
||||
'drums/11-cowbell.mp3': require('!buffer-loader!./assets/drums/11-cowbell.mp3'),
|
||||
'drums/12-triangle.mp3': require('!buffer-loader!./assets/drums/12-triangle.mp3'),
|
||||
'drums/13-bongo.mp3': require('!buffer-loader!./assets/drums/13-bongo.mp3'),
|
||||
'drums/14-conga.mp3': require('!buffer-loader!./assets/drums/14-conga.mp3'),
|
||||
'drums/15-cabasa.mp3': require('!buffer-loader!./assets/drums/15-cabasa.mp3'),
|
||||
'drums/16-guiro.mp3': require('!buffer-loader!./assets/drums/16-guiro.mp3'),
|
||||
'drums/17-vibraslap.mp3': require('!buffer-loader!./assets/drums/17-vibraslap.mp3'),
|
||||
'drums/18-cuica.mp3': require('!buffer-loader!./assets/drums/18-cuica.mp3'),
|
||||
'instruments/1-piano/24.mp3': require('!buffer-loader!./assets/instruments/1-piano/24.mp3'),
|
||||
'instruments/1-piano/36.mp3': require('!buffer-loader!./assets/instruments/1-piano/36.mp3'),
|
||||
'instruments/1-piano/48.mp3': require('!buffer-loader!./assets/instruments/1-piano/48.mp3'),
|
||||
'instruments/1-piano/60.mp3': require('!buffer-loader!./assets/instruments/1-piano/60.mp3'),
|
||||
'instruments/1-piano/72.mp3': require('!buffer-loader!./assets/instruments/1-piano/72.mp3'),
|
||||
'instruments/1-piano/84.mp3': require('!buffer-loader!./assets/instruments/1-piano/84.mp3'),
|
||||
'instruments/1-piano/96.mp3': require('!buffer-loader!./assets/instruments/1-piano/96.mp3'),
|
||||
'instruments/1-piano/108.mp3': require('!buffer-loader!./assets/instruments/1-piano/108.mp3'),
|
||||
'instruments/2-electric-piano/60.mp3': require('!buffer-loader!./assets/instruments/2-electric-piano/60.mp3'),
|
||||
'instruments/3-organ/60.mp3': require('!buffer-loader!./assets/instruments/3-organ/60.mp3'),
|
||||
'instruments/4-guitar/60.mp3': require('!buffer-loader!./assets/instruments/4-guitar/60.mp3'),
|
||||
'instruments/5-electric-guitar/60.mp3': require('!buffer-loader!./assets/instruments/5-electric-guitar/60.mp3'),
|
||||
'instruments/6-bass/36.mp3': require('!buffer-loader!./assets/instruments/6-bass/36.mp3'),
|
||||
'instruments/6-bass/48.mp3': require('!buffer-loader!./assets/instruments/6-bass/48.mp3'),
|
||||
'instruments/7-pizzicato/60.mp3': require('!buffer-loader!./assets/instruments/7-pizzicato/60.mp3'),
|
||||
'instruments/8-cello/36.mp3': require('!buffer-loader!./assets/instruments/8-cello/36.mp3'),
|
||||
'instruments/8-cello/48.mp3': require('!buffer-loader!./assets/instruments/8-cello/48.mp3'),
|
||||
'instruments/8-cello/60.mp3': require('!buffer-loader!./assets/instruments/8-cello/60.mp3'),
|
||||
'instruments/9-trombone/36.mp3': require('!buffer-loader!./assets/instruments/9-trombone/36.mp3'),
|
||||
'instruments/9-trombone/48.mp3': require('!buffer-loader!./assets/instruments/9-trombone/48.mp3'),
|
||||
'instruments/9-trombone/60.mp3': require('!buffer-loader!./assets/instruments/9-trombone/60.mp3'),
|
||||
'instruments/10-clarinet/48.mp3': require('!buffer-loader!./assets/instruments/10-clarinet/48.mp3'),
|
||||
'instruments/10-clarinet/60.mp3': require('!buffer-loader!./assets/instruments/10-clarinet/60.mp3'),
|
||||
'instruments/11-saxophone/36.mp3': require('!buffer-loader!./assets/instruments/11-saxophone/36.mp3'),
|
||||
'instruments/11-saxophone/60.mp3': require('!buffer-loader!./assets/instruments/11-saxophone/60.mp3'),
|
||||
'instruments/11-saxophone/84.mp3': require('!buffer-loader!./assets/instruments/11-saxophone/84.mp3'),
|
||||
'instruments/12-flute/60.mp3': require('!buffer-loader!./assets/instruments/12-flute/60.mp3'),
|
||||
'instruments/12-flute/72.mp3': require('!buffer-loader!./assets/instruments/12-flute/72.mp3'),
|
||||
'instruments/13-wooden-flute/60.mp3': require('!buffer-loader!./assets/instruments/13-wooden-flute/60.mp3'),
|
||||
'instruments/13-wooden-flute/72.mp3': require('!buffer-loader!./assets/instruments/13-wooden-flute/72.mp3'),
|
||||
'instruments/14-bassoon/36.mp3': require('!buffer-loader!./assets/instruments/14-bassoon/36.mp3'),
|
||||
'instruments/14-bassoon/48.mp3': require('!buffer-loader!./assets/instruments/14-bassoon/48.mp3'),
|
||||
'instruments/14-bassoon/60.mp3': require('!buffer-loader!./assets/instruments/14-bassoon/60.mp3'),
|
||||
'instruments/15-choir/48.mp3': require('!buffer-loader!./assets/instruments/15-choir/48.mp3'),
|
||||
'instruments/15-choir/60.mp3': require('!buffer-loader!./assets/instruments/15-choir/60.mp3'),
|
||||
'instruments/15-choir/72.mp3': require('!buffer-loader!./assets/instruments/15-choir/72.mp3'),
|
||||
'instruments/16-vibraphone/60.mp3': require('!buffer-loader!./assets/instruments/16-vibraphone/60.mp3'),
|
||||
'instruments/16-vibraphone/72.mp3': require('!buffer-loader!./assets/instruments/16-vibraphone/72.mp3'),
|
||||
'instruments/17-music-box/60.mp3': require('!buffer-loader!./assets/instruments/17-music-box/60.mp3'),
|
||||
'instruments/18-steel-drum/60.mp3': require('!buffer-loader!./assets/instruments/18-steel-drum/60.mp3'),
|
||||
'instruments/19-marimba/60.mp3': require('!buffer-loader!./assets/instruments/19-marimba/60.mp3'),
|
||||
'instruments/20-synth-lead/60.mp3': require('!buffer-loader!./assets/instruments/20-synth-lead/60.mp3'),
|
||||
'instruments/21-synth-pad/60.mp3': require('!buffer-loader!./assets/instruments/21-synth-pad/60.mp3')
|
||||
};
|
|
@ -22,6 +22,10 @@ const base = {
|
|||
query: {
|
||||
presets: ['es2015']
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.mp3$/,
|
||||
loader: 'file-loader'
|
||||
}]
|
||||
},
|
||||
plugins: process.env.NODE_ENV === 'production' ? [
|
||||
|
@ -62,13 +66,7 @@ module.exports = [
|
|||
output: {
|
||||
libraryTarget: 'commonjs2',
|
||||
path: path.resolve('dist', 'node')
|
||||
},
|
||||
plugins: base.plugins.concat([
|
||||
new CopyWebpackPlugin([{
|
||||
from: './src/extensions/scratch3_music/assets',
|
||||
to: 'assets/scratch3_music'
|
||||
}])
|
||||
])
|
||||
}
|
||||
}),
|
||||
// Playground
|
||||
defaultsDeep({}, base, {
|
||||
|
|
Loading…
Reference in a new issue