Skip to content

Embedding the tiny player

Igor Zinken edited this page Mar 4, 2020 · 19 revisions

The Efflux Tiny Player can be used to play back an Efflux song using a lightweight, headless JavaScript API which can be embedded in a web page or used in demos. The Tiny Player reuses the same code as the full blown Efflux application to ensure songs and instruments sound the same, have the same features and remain in sync whenever updates occur.

The Tiny Player is aimed to be as small as possible and while it reuses the same code as Efflux itself, it does not include Vue nor its reactivity model. Error messages are also kept to a bare minimum. Efforts to squeeze every last byte out of the package are welcomed, but should not come at the expense of readability and maintainability of the shared code. Keep in mind that maintainable inline Tiny Player code can be written while still being minified through the build process. Import used functions instead of entire namespaces to benefit from tree shaking. If your target environment supports it, transpilation to ES5 can be omitted, meaning no polyfills are added, greatly reducing the output file size.

The Webpack configuration of the Tiny Player build is located in ./webpack.config.tiny.js.

Tiny Player is still under development

The current status of the Tiny Player is that it can load and play back songs reusing all of Efflux' audio capabilities. It is however still quite large in filesize and further optimizations will be done to minimize the total output size.

Building the Tiny Player

Simply execute the following command from the repository root (after having resolved all NPM dependencies) :

npm run tiny

after which ./dist/tiny.js is created. This file can be included in a webpage and will expose an Object called eTiny onto Window.

Tiny Player API

The eTiny Object exposes the following methods:

window.eTiny = {
    l: function( xtkObject, optHandler ),
    p: function(),
    s: function(),
    on: function( eventObject ),
    off: function( generatedEventObject ),
    a: function()
};

l (load) : is invoked with the definition of an .XTK song, either as an Object or stringified JSON. This should be called directly after a user interaction event (such as a click) as this will initialize the audioContext on demand, the reason being that automatic audio playback is disabled on certain browsers / devices as the generation of noise should be user initiated. It is your responsibility to fetch / create the .XTK content outside of the Tiny Player. Apart from creating the audioContext, this method will generate the audio events and setup the instruments and modules for playback. Boolean result / logged Error will indicate whether the player is ready for playback. The only reason for failure would be audio playback not being supported in the environment, or given .XTK song being invalid.

This method also accepts an optional secondary argument optHandler which is a function that is invoked whenever the sequencer encounters an external event instruction (defined by code EE). The callback will receive an Object structure { c: number, t: number } where c is an 8-bit value (0x00-0xFF range) defined for the EE event and t is the offset (in seconds) of the event relative to the song start. It's up to you to map these values to a meaningful action. You can use this to sync an event to the sequence of your song, timed at the sample level.

p (play) : starts playback of the song.

s (stop) : stops playback of the song.

j (jump) : jumps to a pattern of choice. Accepts Number value (will be clamped within song pattern range)

on (noteOn) : plays a note for a given instrument. Returns unique event Object generated to synthesize the event (to be passed to the off method to halt playback). Accepts the following Object:

{
    f: number,  // frequency of note in Hz
    i: number,  // index of instrument (defined in loaded song) to use
    a: number,  // number of event action (defaults to 1 for 'noteOn')
    t: number,  // number, audioContext time at which to start playback, defaults to instant playback on invocation
    mp: Object  // Object, optional defines module parameter change   
}

off (noteOff) : stops playing note started with on(). Argument is the Object generated and returned by on().

a (audioContext) : retrieve the generated AudioContext. This can be used in case you want to hook into the audio (for instance: to create an audio visualizer).

Clone this wiki locally