Merge pull request #936 from ericrosenbaum/feature/require-music-assets

Feature/require music assets
This commit is contained in:
Eric Rosenbaum 2018-02-16 10:25:31 -05:00 committed by GitHub
commit ca08cd69e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 37 deletions

View file

@ -33,12 +33,14 @@
"babel-eslint": "^7.1.1", "babel-eslint": "^7.1.1",
"babel-loader": "^7.0.0", "babel-loader": "^7.0.0",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"buffer-loader": "0.0.1",
"copy-webpack-plugin": "4.2.1", "copy-webpack-plugin": "4.2.1",
"decode-html": "2.0.0", "decode-html": "2.0.0",
"escape-html": "1.0.3", "escape-html": "1.0.3",
"eslint": "^4.5.0", "eslint": "^4.5.0",
"eslint-config-scratch": "^5.0.0", "eslint-config-scratch": "^5.0.0",
"expose-loader": "0.7.4", "expose-loader": "0.7.4",
"file-loader": "^1.1.6",
"format-message": "5.2.1", "format-message": "5.2.1",
"format-message-cli": "5.2.1", "format-message-cli": "5.2.1",
"gh-pages": "^1.1.0", "gh-pages": "^1.1.0",

View file

@ -5,6 +5,17 @@ const Cast = require('../../util/cast');
const MathUtil = require('../../util/math-util'); const MathUtil = require('../../util/math-util');
const Timer = require('../../util/timer'); 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. * Icon svg to be displayed at the left edge of each extension block, encoded as a data URI.
* @type {string} * @type {string}
@ -73,21 +84,20 @@ class Scratch3MusicBlocks {
} }
/** /**
* Download and decode the full set of drum and instrument sounds, and * Decode the full set of drum and instrument sounds, and store the audio buffers in arrays.
* store the audio buffers in arrays.
*/ */
_loadAllSounds () { _loadAllSounds () {
const loadingPromises = []; const loadingPromises = [];
this.DRUM_INFO.forEach((drumInfo, index) => { this.DRUM_INFO.forEach((drumInfo, index) => {
const fileName = `drums/${drumInfo.fileName}`; const filePath = `drums/${drumInfo.fileName}`;
const promise = this._loadSound(fileName, index, this._drumBuffers); const promise = this._storeSound(filePath, index, this._drumBuffers);
loadingPromises.push(promise); loadingPromises.push(promise);
}); });
this.INSTRUMENT_INFO.forEach((instrumentInfo, instrumentIndex) => { this.INSTRUMENT_INFO.forEach((instrumentInfo, instrumentIndex) => {
this._instrumentBufferArrays[instrumentIndex] = []; this._instrumentBufferArrays[instrumentIndex] = [];
instrumentInfo.samples.forEach((sample, noteIndex) => { instrumentInfo.samples.forEach((sample, noteIndex) => {
const fileName = `instruments/${instrumentInfo.dirName}/${sample}`; const filePath = `instruments/${instrumentInfo.dirName}/${sample}`;
const promise = this._loadSound(fileName, noteIndex, this._instrumentBufferArrays[instrumentIndex]); const promise = this._storeSound(filePath, noteIndex, this._instrumentBufferArrays[instrumentIndex]);
loadingPromises.push(promise); loadingPromises.push(promise);
}); });
}); });
@ -97,35 +107,48 @@ class Scratch3MusicBlocks {
} }
/** /**
* Download and decode a sound, and store the buffer in an array. * Decode a sound and store the buffer in an array.
* @param {string} fileName - the audio file name. * @param {string} filePath - the audio file name.
* @param {number} index - the index at which to store the audio buffer. * @param {number} index - the index at which to store the audio buffer.
* @param {array} bufferArray - the array of buffers in which to store it. * @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) { _storeSound (filePath, index, bufferArray) {
if (!this.runtime.storage) return; 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) return;
if (!this.runtime.audioEngine.audioContext) 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; const context = this.runtime.audioEngine.audioContext;
// Check for newer promise-based API // Check for newer promise-based API
if (context.decodeAudioData.length === 1) { if (context.decodeAudioData.length === 1) {
return context.decodeAudioData(soundAsset.data.buffer); return context.decodeAudioData(soundBuffer);
} else { // eslint-disable-line no-else-return } else { // eslint-disable-line no-else-return
// Fall back to callback API // Fall back to callback API
return new Promise((resolve, reject) => return new Promise((resolve, reject) =>
context.decodeAudioData(soundAsset.data.buffer, context.decodeAudioData(soundBuffer,
buffer => resolve(buffer), buffer => resolve(buffer),
error => reject(error) error => reject(error)
) )
); );
} }
})
.then(buffer => {
bufferArray[index] = buffer;
});
} }
/** /**

View 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')
};

View file

@ -22,6 +22,10 @@ const base = {
query: { query: {
presets: ['es2015'] presets: ['es2015']
} }
},
{
test: /\.mp3$/,
loader: 'file-loader'
}] }]
}, },
plugins: process.env.NODE_ENV === 'production' ? [ plugins: process.env.NODE_ENV === 'production' ? [
@ -62,13 +66,7 @@ module.exports = [
output: { output: {
libraryTarget: 'commonjs2', libraryTarget: 'commonjs2',
path: path.resolve('dist', 'node') path: path.resolve('dist', 'node')
}, }
plugins: base.plugins.concat([
new CopyWebpackPlugin([{
from: './src/extensions/scratch3_music/assets',
to: 'assets/scratch3_music'
}])
])
}), }),
// Playground // Playground
defaultsDeep({}, base, { defaultsDeep({}, base, {