Superpowered v2.7.2 is now available

Patrick Vlaskovits

It's been a long time coming, but the new release of Superpowered has lots of significant changes both big and small. This is potentially a breaking change for your applications, so get ready to potentially make changes if you'd like to upgrade to the latest and greatest.

General updates

Time stretching algorithms

We've made some tweaks to the algorithms we use in our TimeStretching class to provide silky smooth time and pitch manipulations for audio that don't contain many sonic transients. More specifically, we've updated the algorithm used when you use the TimeStretching.sound property of 2.

Given that Superpowered's AdvancedAudioPlayer class also uses the TimeStretching class internally, that has also inherited the change. Likewise, set AdvancedAudioPlayer.timeStretchingSound property also to 2 to use our best (although most CPU intensive) time stretching algorithm.

AdvancedAudioPlayer new method

You can now call the setBendOffsetMs method on the AdvancedAudioPlayer to set the distance (in milliseconds) to the beatgrid while using pitch bend for correction.

Apple updates

iOS 18 audio stuttering

As some of you may have noticed, iOS 18 has been quite a headache for audio applications across the board due to an undocumented change to the AVAudioSession class, which saw random buffer sizes being used.

In the latest version of Superpowered, we removed the chance of buffer length variability by internally calculating a valid buffer size to be used that is always exactly a power of two.

This calculated value is then used when calling setPreferredIOBufferDuration of the AVAudioSession, resolving the spluttering audio issue you may have experienced in iOS 18.

This was a change to our open-source SuperpoweredIOSAudioIO class available in our main native Superpowered GitHub repo, so update these to the latest versions and you're good to go on iOS 18… snap, crackle and pop free.

Mac Catalyst library

We've fixed the use of Superpowered in Mac Catalyst applications, no changes required, just import as usual.

VisionOS

The Superpowered VisionOS library is now packaged alongside the other apple libraries, no longer a standalone library framework.

Important: If your project is running on VisionOS, you'll need to remove the libSuperpoweredAudio.xcframework from your Xcode project and instead use the generic libSuperpoweredAudio.xcframework

Android updates

Android USB Audio IO

We fixed an improperly calculated buffer size error which caused audio input/output not working when using external USB audio interfaces with Android devices.

Memory Page size

We now support Android 15's new page size of 16KB rather than 4KB.

AdvancedAudioPlayer AudioInMemory pointer

We've resolved an issue caused by using mismatched integer types for pointer address storage when calling openPCM16AudioInMemory on the AdvancedAudioPlayer class.

HTTP requests/responses

We've fixed a bug where the full response headers of a HTTP request were not being forwarded on correctly.

JS/WebAssembly updates

Out with the old, in with the new! The new Superpowered v2.7.2 JS/WebAssembly release sees a major reworking to our Javascript and WebAssembly to significantly optimise performance and improve your developer experience.

Running performant audio on the web has come on a lot since we initially released superpowers. Native ES6 support, the WebAudio API and WebAssembly W3C standards have all advanced over time and, slowly but surely, the browsers have caught up with the standards. We now utatlise some of these latest advances to bring you Superpowered on the web, with two specific areas to bring attention to.

ES6 Modules

Without a single tear in our eye, we are ready to finally wave goodbye to non-standard library importing. You should now use modern ES6 syntax to import Superpowered classes from our library on the main thread, in AudioWorkletsProcessor scripts and in any custom Workers you may have created.

You should now use this ES6 syntax everywhere you need to import Superpowered.

If you've using Superpowered from NPM and bundling your dependencies use

import { SuperpoweredGlue, SuperpoweredWebAudio } from “@superpoweredsdk/web”

To import directly from the web at runtime like in the case of AudioWorkletProcessor or custom Worker scripts use

import { SuperpoweredGlue, SuperpoweredWebAudio } from “https://cdn.jsdelivr.net/npm/@superpoweredsdk/web@2.7.2/dist/Superpowered.js

Important: Please make sure that you are matching the version numbers of Superpowered in you package.json and when importing via the CDN above.

ES2020 Private fields

Please also note that we're using the ES2020 standardized private class fields in our Javascript library code now as part of our effort to modernise our code. We've found that some older webpack/babel configurations are not setup to work with the newer syntax out of the box, so if that's the case you'll need to add the required plugins to your setup. Alternatively, you can also avoid the troublesome transpiling and bundling by importing the Superpowered modules at runtime with a URL rather than importing your the installed library in your package.json.

Please see our JS Getting Started Guide for guidance for more help with getting Superpowered up and running on the web.

ScriptProcessorNode removal

Before the universal browser adoption of the now standardized AudioWorkletProcessorNode, the ScriptProcessorNode was an early way to run WebAssembly assisted audio processing in the browser. It was a great first step in the WebAudio API specification but was ultimatly doomed for real-time audio processing due to the fact that it performed audio processing on the same thread as the browser DOM rendering and JS. With the old ScriptProcessorNode, if the browser screen was resized, or some other Javascript on the main thread took a while to complete, audio processing suffered, often resulting in audible dropouts.

Over the years, we have been moving away from using the ScriptProcessorNode but it is only now that we've seen a broad enough adoption (93%) of the AudioWorkletProcessor, that we can finally have a sigh of relief and remove all of the old code that used the ScriptProcessorNode in any way shape or form. Audio processing in Superpowered across all browsers, is now performed in it's own dedicated performant audio thread.

Typescript JSDoc support

We've added shiny new Typescript support to the SuperpoweredGlue and SuperpoweredWebAudio classes to streamline your developer experience and link directly to our documentation site if in need of more detail.

WASM optimizations

We have optimized the WebAssembly glue code to use a single DataView rather than hundreds of TypedArrays. This has significantly sped up both initialization and member calls to the Supepowerred WASM thats running behind the scenes.

This also means calling Superpowered methods in an iteration, such as when we are analysing audio, is roughly 2x faster now.

SharedArrayBuffer support

Previously, if you've ever tried to download and decode audio in Superpowered on the web while playback is taking place, you may have noticed a tiny glitch in the audio. This was due to the WebAssembly memory allocation taking place, which sometimes disrupted the audio thread in the browser.

Under the hood, we've now added the ability to sit your Superpowered instances on top of a SharedArrayBuffer which can be shared (transferred) to any thread you need, where direct memory access can be performed. Optionally, by allocating a larger amount of memory upfront, we are able to bypass the browsers need to request more memory from the OS, resulting in silky smooth audio.

Stay tuned, we'll shortly be releasing utilities in Superpowered v2.7.3 that'll make working with the shared memory much easier in practise. In fact, you'll not even need to know what a SharedArrayBuffer is by the time we're done!

Important: To use SharedArrayBuffers in production you'll need to make sure your site is complying with the relatively new definition of a "secure context".

In practise, as of October 2024, this means you'll need to be sending some response headers from your public JS application web server and it'll also need to be served ALL over HTTPS. See the MDN docs for details.

To quickly check if your hosting setup is correct, you can run window.crossOriginIsolated in the browsers console on your site which will return a boolean representing the current compliance.



Enjoy!
The Superpowered Team

  • superpowered documentation
  • superpowered reference
  • superpowered examples
  • superpowered tutorial