Home Reference Source Repository

Binaural

This library permits to render sources in three-dimensional space with binaural audio.

This library provides an access to a server, in order to load a set of Head-related transfer functions (HRTF). The set of filters applies to any number of sources, given their position, and a listener.

This library is compatible with the Web Audio API. The novelty of this library is that it permits to use a custom HRTF dataset (see T. Carpentier article).

It is possible to use it without a server, with a direct URL to an HRTF set.

Documentation

You can consult the API documentation for the complete documentation.

BinauralPanner

A BinauralPanner is a panner for use with the Web Audio API. It spatialises multiple audio sources, given a set of head-related transfer functions HRTFs, and a listener.

ServerDataBase

The public server that hosts a database of individual HRTFs is available for beta-testers only and will open to public in 2016.

The ServerDataBase retrieves a catalogue from a SOFA server. From the catalogue, it get URLs matching optional filters: data-base, sample-rate, and any free pattern.

HRTF dataset

You can use any HRTF data-set that follows the SOFA standard, in JSON format, using finite impulse responses (FIR). Second-order sections (SOS) are not supported, yet. See the examples HRTF directory for a few samples.

Coordinate system types

See the files in src/geometry, for conversions:

Examples

Please see the examples directory for complete code (on branch gh-pages), and the examples online.

See also the API documentation for the complete options.

BinauralPanner

Given an audio element, and a global binaural module,

<html>
    <head>
        <script src="../binaural.js"></script>
    </head>
    <body>
        <audio id="source" src="./snd/breakbeat.wav" controls loop></audio>
    </body>
</html>

create a source audio node,

var audioContext = new AudioContext();
var $mediaElement = document.querySelector('#source');
var player = audioContext.createMediaElementSource($mediaElement);

instantiate a BinauralPanner and connect it.

var binauralPanner = new binaural.audio.BinauralPanner({
    audioContext,
    crossfadeDuration: 0.05, // in seconds
    coordinateSystem: 'sofaSpherical', // [azimuth, elevation, distance]
    sourceCount: 1,
    sourcePositions: [ [0, 0, 1] ], // initial position
});
binauralPanner.connectOutputs(audioContext.destination);
binauralPanner.connectInputByIndex(0, player);

Load an HRTF set (this returns a Promise).

binauralPanner.loadHrtfSet(url)
    .then(function () {
        console.log('loaded');
    })
    .catch(function (error) {
        console.log('Error while loading ' + url + error.message);
    });

Then, any source can move:

$azimuth.on("input", function(event) {
    // get current position
    var position = binauralPanner.getSourcePositionByIndex(0);

    // update azimuth
    position[0] = event.target.value;
    binauralPanner.setSourcePositionByIndex(0, position);

    // update filters
    window.requestAnimationFrame(function () {
        binauralPanner.update();
    });
});

Note that a call to the update method actually updates the filters.

ServerDataBase

Instantiate a ServerDataBase

var serverDataBase = new binaural.sofa.ServerDataBase();

and load the catalogue from the server. This returns a promise.

var catalogLoaded = serverDataBase.loadCatalogue();

Find URLs with HRIR convention, COMPENSATED equalisation, and a sample-rate matching the one of the audio context.

var urlsFound = catalogLoaded.then(function () {
    var urls = serverDataBase.getUrls({
        convention: 'HRIR',
        equalisation: 'COMPENSATED',
        sampleRate: audioContext.sampleRate,
    });
    return urls;
})
.catch(function(error) {
    console.log('Error accessing HRTF server. ' + error.message);
});

Then, a BinauralPanner can load one of these URLs.

urlsFound.then(function(urls) {
    binauralPanner.loadHrtfSet(urls[0])
        .then(function () {
            console.log('loaded');
        })
        .catch(function (error) {
            console.log('Error while loading ' + url
                + error.message);
        });
});

Issues

To do

Developers

The source code is in the src directory, in ES2015 standard. npm run compile with Babel to the dist directory. Note that there is a .babelrc file. npm run bundle runs the linters, the tests, generates the documentation, and compiles the code.

Commit the source files to the branch develop, and update the version in package.json if this is intended to be a release.

On the master branch, merge from the develop branch. Generate and commit the documentation and the distribution files. Put a release tag that corresponds to the version in package.json.

On the gh-pages branch, merge from the master branch. Commit the examples, and the extra files (audio and HRTF set files).

Style

npm run lint to check that the code conforms with .eslintrc and .jscsrc files. The rules derive from AirBnB with these major points:

Test

For any function or method, there is at least a test. The hierarchy in the test directory is the same as in the src directory.

Examples for specific testing, when developing or resolving an issue:

Documentation

Document any public function and method with JSDoc, and generate the HTML pages with npm run doc. At this point, neither jsdoc nor esdoc gives perfect transcription. (See the jsdoc.json and esdoc.json files.)

License

This module is released under the BSD-3-Clause license.

Acknowledgements

This research was developped by both Acoustic And Cognitive Spaces and Analysis of Musical Practices IRCAM research teams. A previous version was part of the WAVE project, funded by ANR (French National Research Agency). The current version, supporting multiple sources and a listener, the SOFA standard, and the access to a server, is part of the CoSiMa project, funded by ANR.