Photo by on Steve Harvey Unsplash With the shipment of the feature in 64, it’s probably reasonable to say 2018 was a good year for the Web Audio API. Nearly a year later after its release, there are still relatively few examples outside of and for developers to draw from. These serve as great introductions to the interface, but with relatively few user-created examples to learn from, we’re left to our own devices when figuring out how to implement it out in the wild. The reality is, the task of getting AudioWorklets to play nice with React and other UI frameworks isn’t as straightforward as it might seem. The aim of this article is to show programmers already familiar with the Web Audio API how they can connect AudioWorklets to a React interface. For more info on the AudioWorklet specification, see the links at the very bottom of this article. AudioWorklet Chrome the resources at Google Chrome Labs dsp.audio Background As a conservatory-trained musician entering the world of software engineering and DSP via , I was (and still am) giddy at the prospect of creating web interfaces with a dedicated audio rendering thread. In short, upon hearing the news, I was ready to blast off! I fired up , copied some examples from Chrome Labs, and ran only to receive the following error: computational musicology create-react-app yarn start Failed to compile../src/worklet/worklet-node.js Line 2: 'AudioWorkletNode' is not defined no-undef Is my version of Chrome outdated? It’s not? Why is AudioWorkletNode undefined? Thankfully was quick to relieve my confusion on StackOverflow (thanks, Dan!): Dan Abramov Create React App is configured to enforce that you access browser APIs like this with a qualifier. This way it's clear you're using a global and didn't forget to import something (which is very common). window. This should work: class MyWorkletNode extends window.AudioWorkletNode { (In the future releases, ESLint will be aware of this global by default, and you will be able to remove ) window. Ok, no big deal! We should be good now, right? Not quite. Trying to load my AudioWorklet processor using threw the vaguest, most damning error no developer would ever want to come across: context.audioWorklet.addModule() DOMException: The user aborted a request. Back to StackOverflow I went. John Weisz at pointed out that this error may be a in the Chromium module loader: AudioNodes bug …it parses the file by removing whitespace, which in turn causes it to have JavaScript syntax errors everywhere, which then finally causes this generic non-explanatory error message to show up. worklet/processor.js He went on to suggest serving the module with specified headers . I didn’t know where or how to specify AudioWorklet content headers, so I took a long break from AudioWorklets with the hopes that more examples would pop up over time. Content-Type: application/javascript 7 Months Later: An Unexpectedly Simple Solution Serve your AudioWorklet processors from the folder. Just do it. I was fiddling around and discovered that the method points there by default. No imports, no requires, no needed. public addModule('path/to/your/module') {process.env.PUBLIC_URL}/my-worklet-processor With all that behind us, it would be a great exercise to port the four audio processing demos from to React: the Bypasser, One Pole Filter, Noise Generator, and BitCrusher. If you’re impatient and want to dig into the entire codebase immediately, the link to the GitHub repo is listed at the very bottom. Simply clone it, install dependencies with , and run the app with . Google Chrome Labs yarn install yarn start to view the demo. Click here In the following walkthrough, we’ll create a dead simple UI over create-react-app boilerplate code. We’ll work with components and gain familiarity with AudioWorklets by making slight modifications to each processor to accept data via the messagePort to toggle it on or off. The user will be able to choose between the four audio processing demos from a drop-down menu. We’ll stick a button next to the drop-down which will toggle the current node on and off. That’s it! If you want to see the demo in action, click the link to the left (it’s above if you’re viewing on mobile). Ant Design Below is a broad overview of the project we are going to create. Directories and files we are adding to create-react-app boilerplate are bolded and italicized with neighboring descriptions. | — README.md| — package.json| — public| | — favicon.ico| | — index.html| | — manifest.json | — src| | — App.css| | — App.js /* Main UI */| | — App.test.js | | — index.css| | — index.js| | — logo.svg| — serviceWorker.js| — yarn.lock | ` — worklet /*Contains AudioWorkletProcessors*/ _| | — bit-crusher-processor.js| | — bypass-processor.js| | — noise-generator.js| ` — one-pole-processor.js_ | | — Demos.js /*Functions that interface with the processors*/ The Barebones UI Step 1: create-react-app react-audio-worklet Step 2: Install dependencies. In this case, we’re just using one package for the UI, so go ahead and run the command . Make sure to into yarn add antd import 'antd/dist/antd.css' index.js. Step 3: Bring in the necessary components to create a drop-down menu and set up the initial state: Module Selection/Loading and Audio Toggling Step 1: Keeping separation of concerns in mind, let’s include callbacks to trigger the audio demos from a separate file called Demos.js: Step 2: Create AudioWorklet processers in public/worklet: Note: Like the demos, these are practically the Chrome Team’s code verbatim with the slight modification of binding the port’s onMessage function to the AudioWorkletProcessor for better readability. Step 3: Now we’ll create methods in to handle the selection/loading of processor modules, as well as toggling playback of the currently selected module: App.js Before we forget, let’s import into the main app. Your final should now read as follows: Demos.js App.js Now go ahead and run and listen to those demos. Hear that? That’s the sweet sound of Web Audio processing on its own dedicated rendering thread! yarn start Conclusion I hope this article has clarified how to avoid some common hiccups that many may encounter when trying to integrate AudioWorklets into React. I also hope it has helped in gaining familiarity in using the Worklet API itself. The Chrome WebAudio team has introduced powerful technology to the web platform with AudioWorklets — and with on the rise, the future of DSP on the web is looking bright. WebAssembly Links GitHub Repo Enter AudioWorklet The AudioWorklet Interface Web Audio API | MDN About the Author Nathan Bloomfield is a conservatory-trained musician who collided with the world of software engineering and DSP via computational musicology. | | | LinkedIn Instagram Twitter bloom510.art