Getting Started
August 23, 2021 ยท View on GitHub
The entirety of Wax is available in a single package from npm, named wax-core. Install it into your project with:
npm i --save wax-core
Create a single entry point, simple.jsx, and replicate the following imports and audio graph.
import {
createAudioElement,
renderAudioGraph,
AudioGraph,
Oscillator,
Gain,
StereoPanner,
Destination,
setValueAtTime,
exponentialRampToValueAtTime,
} from 'wax-core';
renderAudioGraph(
<AudioGraph>
<Oscillator
frequency={[
setValueAtTime(200, 0),
exponentialRampToValueAtTime(800, 3),
]}
type="square"
endTime={3}
/>
<Gain gain={0.2} />
<StereoPanner pan={-0.2} />
<Destination />
</AudioGraph>
);
While <AudioGraph /> does nothing special at present, it may manipulate its children in future versions of Wax. Please ensure you always specify an AudioGraph as the root element of the tree.
But how do we actually build this? How can we instruct a transpiler that these JSX constructs should specifically target Wax? Firstly, let's look at the first binding we import from wax-core:
import {
createAudioElement,
...
} from 'wax-core';
Why are we importing this is we aren't calling it anywhere? Oh, but we are; when our JSX is transpiled, it'll resolve to invocations of createAudioElement. It is the Wax equivalent of React.createElement, and follows the exact same signature!
renderAudioGraph(
createAudioElement(
AudioGraph,
null,
createAudioElement(
Oscillator,
{
frequency: [
setValueAtTime(200, 0),
exponentialRampToValueAtTime(800, 3)
],
type: 'square',
endTime: 3,
},
),
createAudioElement(Gain, { gain: 0.2 }),
createAudioElement(StereoPanner, { pan: -0.2 }),
createAudioElement(Destination, null),
)
);
To achieve this transformation, we can use Babel and the transform-react-jsx plugin; the latter exposes a pragma option that we can configure to transform JSX to createAudioElement calls:
{
"plugins": [
["@babel/transform-react-jsx", {
"pragma": "createAudioElement"
}]
]
}
Despite the name, this plugin performs general JSX transformations, defaulting to React.createElement. You do not need React to use Wax!
To create a bundle containing Wax and our app's code, we'll need a build tool that supports ES Modules. For the example apps, we use Rollup and rollup-plugin-babel to respect JSX transpilation (config).
Once we have our bundle, we can load it into a HTML document using a <script> element:
<script src="/index.js"></script>
createAudioElement and ESLint
If you are using ESLint to analyse your code, you may receive this error:
'createAudioElement' is defined but never used.
This is because eslint-plugin-react expects the pragma to be React.createElement. To suppress this error, one should explicitly configure the React plugin in the ESLint config's settings property:
{
"settings": {
"react": {
"pragma": "createAudioElement"
}
}
}
Alternatively, one can specify an @jsx directive at the beginning of your module
/** @jsx createAudioElement */