Skip to content

collective-soundworks/soundworks-plugin-audio-buffer-loader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@soundworks/plugin-audio-buffer-loader

soundworks plugin for loading and managing audio buffers and related json data. Currently limited to .mp3, .wav or .json formats to enforce browser compatibility and support (meaning support for Safari...)

Table of Contents

Installation

npm install @soundworks/plugin-audio-buffer-loader --save

Example

A working example can be found in the https://github.com/collective-soundworks/soundworks-examples repository.

Usage

Server installation

Registering the plugin

// index.js
import { Server } from '@soundworks/core/server';
import pluginAudioBufferLoaderFactory from '@soundworks/plugin-audio-buffer-loader/server';

const server = new Server();
server.pluginManager.register('audio-buffer-loader', pluginAudioBufferLoaderFactory, {}, []);

Requiring the plugin

// MyExperience.js
import { AbstractExperience } from '@soundworks/core/server';

class MyExperience extends AbstractExperience {
  constructor(server, clientType) {
    super(server, clientType);
    // require plugin in the experience
    this.audioBufferLoader = this.require('audio-buffer-loader');
  }
}

Client installation

Registering the plugin

// index.js
import { Client } from '@soundworks/core/client';
import pluginAudioBufferLoaderFactory from '@soundworks/plugin-audio-buffer-loader/client';

const client = new Client();
client.pluginManager.register('audio-buffer-loader', pluginAudioBufferLoaderFactory, {
  // declare files that should be loading when Experience starts, if any
  data: {
    'file-1': 'sounds/88-fingers-short.mp3',
    'file-2': 'sounds/drops-short.mp3',
    'file-3': 'sounds/plane-short.mp3',
  }
}, []);

Requiring the plugin

// MyExperience.js
import { Experience } from '@soundworks/core/client';

class MyExperience extends Experience {
  constructor(client) {
    super(client);
    // require plugin in the experience
    this.audioBufferLoader = this.require('audio-buffer-loader');
  }

  async start() {
    console.log(this.audioBufferLoader.data);
    // {
    //   'file-1': AudioBuffer,
    //   'file-2': AudioBuffer,
    //   'file-3': AudioBuffer,
    // }
  }
}

Loading files

The following API is only available client-side.

This method use the given data structure to load files, the resulting object is a copy of the given object where each path to a .mp3, .wav or .json file is replaced with its corresponding AudioBuffer or JSON object. The resulting object is returned, and is by default mixed into this.audioBufferLoader.data using Object.assign. If override is set to true, this.audioBufferLoader.data is completely replaced with the new object. This behavior aims to give a simple and predictable way to deal with the caching of AudioBuffers, for example reusing a given key will drop the old AudioBuffer and replace it with the new one.

/**
 * @async
 * @param {Object} defObj - The data structure containing the link to the
 *   audio and json files to load
 * @param {Boolean} [override=false] - if true replace the internal cache with
 *   the new object instead of mixing it using `Object.assign`
 * @return defObj mutated with link replaced by `AudioBuffers`
 */
const loadedData = await this.audioBufferLoader.load({
  'file-1': 'sounds/88-fingers-short.mp3',
  'file-2': 'sounds/drops-short.mp3',
  'file-3': 'sounds/plane-short.mp3',
}, true);
// loadedData = {
//   'file-1': AudioBuffer,
//   'file-2': AudioBuffer,
//   'file-3': AudioBuffer,
// }

Getting and subscribing to loading status change

You may want to track loading status to display a waiting screen or whatever feedback.

this.audioBufferLoader.subscribe(state => {
  console.log(state.loading); // > true || false
});

const loadingState = this.audioBufferLoader.get('loading');
// > true || false

Keeping in sync with a directory using the @soundworks/plugin-filesystem

In working situations you may want to dynamically add and remove sound files while your application is running to make tests. The @soundworks/plugin-filesystem can be used in conjunction with the @soundworks/plugin-audio-buffer-loader to ensure your clients AudioBuffers are synced with the content of a given directory.

Assuming the @soundworks/plugin-filesystem is configured to track changes in a directory named soundbank, the client can simply observe these changes to keep AudioBuffers synced as follow:

// MyExperience.js
import { Experience } from '@soundworks/core/client';

class MyExperience extends AbstractExperience {
  constructor(client) {
    super(client);

    this.filesystem = this.require('filesystem');
    this.audioBufferLoader = this.require('audio-buffer-loader');
  }

  async start() {
    super.start();
    // subscribe to directory updates
    this.filesystem.subscribe(() => this.loadSoundbank());
    // initialize with the current content of the directory
    this.loadSoundbank();
  }

  async loadSoundbank() {
    const soundbankTree = this.filesystem.get('soundbank');
    // format tree to create a simple data object
    const defObj = {};

    soundbankTree.children.forEach(leaf => {
      if (leaf.type === 'file') {
        defObj[leaf.name] = leaf.url;
      }
    });
    // load files and clear old cached buffers
    const loadedObject = await this.audioBufferLoader.load(defObj, true);
    // do something with your buffers
  }
}

Credits

The code has been initiated in the framework of the WAVE and CoSiMa research projects, funded by the French National Research Agency (ANR).

License

BSD-3-Clause

About

soundworks plugin for loading and managing audio buffers and related json data.

Resources

License

Stars

Watchers

Forks

Packages

No packages published