Superpowered v2.7.2 is now available
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 TypedArray
s. 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