Source: load-sounds.js

/**
 * @function loadSounds
 * @summary
 * Use this function to load and playback sounds from a manifest.
 * @description
 * For full documentation read the <a target="_blank" href="https://wiki.tremorvideodsp.com/x/cZkvB">Wiki Post</a>
 *
 * This function returns an object with the key "sounds", which is initially an empty object, but
 * will be the augmented with each sound specified in the input parameters opts.manifest and opts.src
 * after they are loaded.
 *
 * Required Parameters:
 * * eventLabel:
 *    * Type: string
 *    * Requirements: Required
 *    * Description: string prepended to event names
 *
 * * opts.manifest is an array of objects, where each object must contain a key "id" and a key "src"
 *
 * Optional Parameters:
 * * opts.root: prefix for absolute or relative URL each src.
 *     Note: If you wish to load sounds from multiple different absolute sources, provide opts.root = '' and provide full absolute paths in each sound src in the manifest.
 *
 * Returns:
 *  {sounds: object}
 *
 * Note:
 *   you should check that the sound.id exists before trying to call .play() on it
 *   you can store other key on each item in the manifest array, such as a "description", which may be useful
 *   when you play your sounds
 *
 * The following event names are emitted:
 * ```
 *   eventLabel + '-LOAD_SOUNDS_COMPLETE'
 *   eventLabel + '-LOAD_SOUNDS_ERROR'
 *   eventLabel + '-LOAD_SOUNDS_PROGRESS'
 *   eventLabel + '-LOAD_SOUNDS_FILE_LOAD'
 * ```
 * Sample Usage:
 * ```
 *   // in Movie Clip CreativeMain
 *   var here = this
 *   var soundsObj = window.$b.snippets.loadSounds({
 *     eventLabel: 'wahSound',
 *     manifest: [
 *      {id: 'wah', src: 'sounds/WAH WAH WAH FAIL.mp3'}
 *     ]
 *   }).sounds
 *   window.$b.on('wahSound-LOAD_SOUNDS_COMPLETE', function (evt) {
 *     here.slateDesign.playBtn.addEventListener('click', function() {
 *       if (soundsObj.wah) {
 *         soundsObj.wah.play()
 *       }
 *     })
 *   })
 * ```
 *
 * @param opts {Object}
 * @param {string} opts.eventLabel a string prepended to the event names
 * @param opts.manifest {Array<{Object}>} each object must contain a key "id" and a key "src"
 * @param opts.root {string=}  prefix for absolute or relative URL each src.
 */
function loadSounds (opts) {
  var sounds = {}
  var defaultObj = { sounds: sounds }

  if (!opts.eventLabel || typeof opts.eventLabel !== 'string') {
    console.error('You must provide a (string) label for the event prefix.')
    return defaultObj
  }

  var eventLabel = opts.eventLabel
  var completeEvent = eventLabel + '-LOAD_SOUNDS_COMPLETE'
  var errorEvent = eventLabel + '-LOAD_SOUNDS_ERROR'
  var progressEvent = eventLabel + '-LOAD_SOUNDS_PROGRESS'
  var fileLoadEvent = eventLabel + '-LOAD_SOUNDS_FILE_LOAD'
  if ((typeof opts !== 'object') || (!(opts.manifest instanceof Array))) {
    console.log('loadSounds must be passed an object with a key "manifest" which contains an array')
    return defaultObj
  }
  var manifest = opts.manifest

  var existingKeys = {}
  for (var i = 0; i < manifest.length; i++) {
    if ((typeof manifest[i] !== 'object') || !(manifest[i].id)) {
      console.log('You must provide a unique id for each sound')
      window.$b.emit(errorEvent)
      return defaultObj
    }
    var id = manifest[i].id
    if (existingKeys[id]) {
      console.log('Manifest[' + i + '].id = ' + id + ' is not unique.')
      window.$b.emit(errorEvent)
      return defaultObj
    }
    existingKeys[id] = true
    if (!manifest[i].src) {
      console.log('You must provide a source file for each sound')
      window.$b.emit(errorEvent)
      return defaultObj
    }
  }

  // Checks if blink is available and if it does attaches the baseUrl
  var baseUrl = ''
  if (typeof window.$b === 'object') {
    baseUrl = window.$b.baseUrl
  }

  var root = opts.root === '' ? '' : opts.root || baseUrl || ''

  var queue = new createjs.LoadQueue(true, root)
  queue.installPlugin(createjs.Sound)
  queue.loadManifest(opts.manifest)
  queue.addEventListener('error', handleError)
  queue.addEventListener('fileload', handleFileLoad)
  queue.addEventListener('complete', handleComplete)
  queue.addEventListener('progress', handleProgress)

  function handleProgress (evt) {
    window.$b.emit(progressEvent, evt)
  }

  function handleFileLoad (evt) {
    var sound = createjs.Sound.createInstance(evt.item.id)

    // Copy item properties from manifest.
    // This allows you to add custom properties within the manifest so that they
    // can be used later once the sound has been loaded.
    sound.manifestItem = evt.item

    sounds[evt.item.id] = sound

    window.$b.emit(fileLoadEvent, evt)
  }

  function handleError (evt) {
    window.$b.emit(errorEvent, evt)
  }

  function handleComplete (evt) {
    window.$b.emit(completeEvent, evt, sounds)
  }

  return {
    sounds: sounds,
    handleProgress: handleProgress,
    handleFileLoad: handleFileLoad,
    handleComplete: handleComplete,
    queue: queue
  }
}

window.$b = window.$b || {}
window.$b.snippets = window.$b.snippets || {}
var snippets = window.$b.snippets
snippets.loadSounds = loadSounds