Package Exports
- ambisonics
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ambisonics) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
JSAmbisonics
A JS library for first-order ambisonic (FOA) and higher-order ambisonic (HOA) processing for browsers, using Web Audio.
Archontis Politis (Aalto University)
David Poirier-Quinot (IRCAM)
Description
JSAmbisonics is a JavaScript library that implements a set of objects for real-time spatial audio processing, using the Ambisonics framework. The objects correspond to typical ambisonic processing blocks, and internally implement Web Audio graphs for the associated operations.
The library is suitable for both FOA and HOA processing, using the following specifications:
- FOA B-format signals with traditional ordering [W X Y Z] and a factor of 1/sqrt(2) on the omnidirectional first channel.
- FOA or HOA (up to 3rd-order) using the Furse-Malham specification.
- FOA or HOA with ACN channel ordering and N3D normalization. This is the default mode, and all internal processing is done using this.
- FOA or HOA with ACN channel ordering and SN3D normalization.
Computation of spherical harmonics and rotations rely on the JavaScript spherical harmonic library contributed by the author here. The HOA code is based on the larger Matlab HOA and Spherical Harmonic Transform libraries contributed by the author in Github. The rotation algorithm is the fast recursive one by Ivanic and Ruedenberg.
The implemented Web Audio classes are:
- monoEncoder: encodes a monophonic sound source to an ambisonic stream of a set order, with real-time control of the panning direction.
- sceneRotator: rotates the sound scene of an ambisonic stream, with real-time control of yaw, pitch, and roll rotation angles.
- sceneMirror: mirrors the sound scene of an ambisonic stream with respect to (front-back), (left-right), or (up-down) axes.
- virtualMic: applies FOA and HOA virtual microphones to an ambionic stream, with real-time control of their orientation and pattern.
- binDecoder: implements an ambisonic to binaural decoding, using user-defined HRTF-based filters. If these are not provided, two plain opposing cardioids are used instead.
- orderLimiter: takes a HOA stream of order N, and outputs the channel-limited HOA stream of order N'<=N
- orderWeight: applies user-specified gains to the channels of the same order, for directional smoothing or psychoacoustic (max energy-vector) decoding
- converters.wxyz2acn: converts a traditional FOA stream to FOA ACN/N3D stream
- converters.acn2wxyz: converts the first-order channels of a HOA stream to traditional FOA stream
- converters.n3d2sn3d: converts an ACN/N3D stream to an ACN/SN3D stream
- converters.sn3d2n3d: converts an ACN/SN3D stream to an ACN/N3D stream
- converters.fuma2acn: converts a FuMa stream to a ACN/N3D stream
- intensityAnalyser: implements an acoustic intensity analysis for visualization of directional information captured in the ambisonic stream.
The library is a work-in-progress, but fully functional. At the moment, demos seem to work fine in Mozilla Firefox and Google Chrome. No other browsers have been checked yet.
Real-time demo (Chrome and Firefox)
See the live Rawgit demo (serving the content of the ./examples folder).
HOA recordings are made by the author in the Communication Acoustics laboratory of Aalto University, using the Eigenmike microphone.
Usage
To add the library to you node project, type in (terminal at project root):
npm install ambisonicsTo use the ambisonic objects, include the JSAmbisonics library in the body of your html code as:
<script type="text/javascript" src=“ambisonics.umd.js"></script>ambisonic encoder is initialized as
var encoder = new ambisonics.monoEncoder(audioContext, order)where audioContext is the current Web Audio context, and order the desired ambisonic order. The input stream comes from an audio node to be spatialized. The azimuth and elevation of the encoded source can be updated at runtime by
encoder.azim = azim_value_in_degrees;
encoder.elev = elev_value_in_degrees;
encoder.updateGains();ambisonic mirror is initialized as
var mirror = new ambisonics.sceneMirror(audioContext, order)The reflection planes (1: front-back), (2: left-right), (3: up-down), or (0: no reflection) can be updated at runtime by
mirror.mirror(planeNo);where planeNo is any of the above integers.
ambisonic rotator is initialized as
var rotator = new ambisonics.sceneRotator(audioContext, order)The yaw (Z-axis rotation), pitch (Y-axis) and roll (X-axis) rotation angles can be updated at runtime by
rotator.yaw = yaw_value_in_degrees;
rotator.pitch = pitch_value_in_degrees;
rotator.roll = roll_value_in_degrees;
rotator.updateRotMtx();ambisonic binaural decoder is initialized as
var binDecoder = new ambisonics.binDecoder(audioContext, order)If no decoding filters are passed to the decoder, an initial decoding based on two opposing cardioids is defined by default. In case binaural decoding filters are available, they should be loaded in a multichannel audioBuffer and passed to the decoder through
binDecoder.updateFilters(audioBuffer);The number of channels of the buffer should be equal or greater to (order+1)^2, which amounts to the number of ambisonic channels for the specified order. The filters can be reset to their default cardioids by
binDecoder.resetFilters();Some FOA and HOA HRTF-based decoding filters are included in the examples.
ambisonic virtual microphone is initialized as
var vmic = new ambisonics.virtualMic(audioContext, order)The virtual microphone is initialized to a hypercardioid of the appropriate order, pointing to the front. The orientation can be updated at runtime by
vmic.azim = azim_value_in_degrees;
vmic.elev = elev_value_in_degrees;
vmic.updateOrientation();The pattern of the microphone can be also updated by
vmic.vmicPattern = string;
vmic.updatePattern();where string can be one of the following:
- "cardioid"
- "supercardioid"
- "hypercardioid"
- "max_rE"
Higher-order cardioids correspond to the normal cardioid raised to the power of order. Higher-order supercardioids correspond to the pattern of that order that maximizes the front-to-back energy ratio. Higher-order hypercardioids correspond to the pattern of that order that maximizes the directivity factor. the max-rE pattern, found in ambisonic decoding literature, corresponds to the pattern of that order that maximizes the (Gerzon) energy vector for diffuse sound.
All objects have an input node object.in and an output node object.out which are used for the connections. The number of channels expected from each input depends on the object (for example a FOA encoder expects a monophonic signal, and outputs 4 channels, a FOA binaural decoder expects 4-channel input and outputs 2 channels, etc.). Example connections:
soundBufferPlayer.connect(encoder.in);
encoder.out.connect(rotator.in);
rotator.out.connect(binDecoder.in);
binDecoder.connect(audioContext.destination);which implements a graph such as:
soundBufferPlayer ------------->encoder------------>rotator---------->binDecoder-------------->out
mono stream HOA stream HOA stream stereo streamand
soundBufferPlayer.connect(vmic.in);
vmic.out.connect(audioContext.destination);with a graph such as:
soundBufferPlayer ------------->vmic------------>out
HOA stream mono streamSee the scripts in the ./examples folder for more insights on how to use the different objects of the library.
Note on the loading of multichannel files for HOA
The HOA processing of order=N requires audio streams of (N+1)^2 channels. Loading HOA recordings or HOA binaural filters from sound files of that many channels seems to be problematic for the browsers. Both Firefox and Chrome seem to be able to handle WAVE and OGG files of up to 8ch. For that reason a helper class is provided that loads individual 8ch files that have been split from the full HOA multichannel file. Usage:
var HOA3soundBuffer;
var order = 3;
var url = "https://address/HOA3_rec1.wav";
var callbackOnLoad = function(mergedBuffer) {
HOA3soundBuffer = mergedBuffer;
}
var HOA3loader = new ambisonics.HOAloader(audioContext, order, url, callbackOnLoad);
HOA3loader.load();The class will try to find files with the provided file name HOA3_rec1.wav but of the form:
HOA3_rec1_01-08ch.wav
HOA3_rec1_09-16ch.wavThe above example for 3rd-order will have exactly two files of 8ch (16 HOA channels). For a 2nd-order example (9 HOA channels) the loader will check for
HOA2_rec1_01-08ch.wav
HOA2_rec1_09-09ch.wavand so on.
Developers
To modify the library you need Node.js installed on your machine. First install the development version of the library:
npm install polarch/JSAmbisonics
and then install the project's dependencies typing in a terminal (opened in project's root):
```bash
npm installYou can then start developing, using the watch utility to dynamically transpile / bundle your code as you write it:
npm run watchand test the changes on the files of the ./examples folder, serving ./index.html with a local http server (see e.g. the http-server node).
When you're satisfied with your changes, create the ambisonics.*.js bundles with:
npm run bundleLicense
The library is released under the BSD 3-Clause License.