Sushi development update - new features available for testing

Hi, hope you’re doing good. In our aim to keep you updated with the latest Elk Audio OS developments. We’ve recently updated the develop branches of Sushi and related projects with some new features. These are changes that are scheduled for the next release of Elk Audio OS but we want to share them with you before to give you a change to try them out. Feedback is always welcome.

There has been several significant features added to Sushi lately. These are the most important updates:

Updated gRPC API with completion notifications.

In the previous version of Sushi’s external API there were no notifications when commands like SessionController::SetState() or AudioGraphController::CreateTrack() actually finished. It was possible to subscribe to TrackUpdate and ProcessorUpdate notifications, but if no notification was received, the user could not know if the command was still in process or had silently failed.

Sushi now allows you to subscribe to AsyncCommandUpdates. It works in the following way: Most set requests now return a CommandResponse message containing a CommandStatus code and a command id.

message CommandResponse
{
    CommandStatus status = 1;
    int32 id = 2;
}

The status can be SUCCESS or any error code, but if the status is ASYNC_RESPONSE, it means the command will be processed by a background thread in Sushi and will eventually result in an AsyncCommandResponse being sent, with the same id and a final status of SUCCESS or an error status.

This will allow users of Sushi to build more responsive control interfaces.

ElkCpp and Elkpy wrapper libraries also contain drop-in implementations that matches command ids to completion notifications in order to make it as easy as possible to write control applications.

Our example GUI written with ElkPy and QT has also been updated to support this API.

CPU core/thread option for tracks

Tracks can now be pinned to specific CPU cores for more finegrained control of the CPU load. The gRPC endpoints AudioGraphController::CreateTrackRequest() and AudioGraphController::CreateMultiBusTrackRequest() now take an optional thread parameter. There is also an optional “thread” member in the json config for tracks.

Thread id in this case doesn’t refer directly to a CPU core, but to an index starting from 0 into the number of parallel threads sushi’s audio processing is configured to run with. I.e. if sushi is started with –multicore-processing=2 valid values for the thread parameter are 0 and 1.

gRPC CpuTiming notifications have also been updated to show cpu usage for each individual core, if sushi is configured with multithreaded audio processing.

As Sushi’s multicore processing is based on twine, this functionality is also available in twine’s WorkerPool implementation.

Zero latency sends

Send and Return plugins can now be zero latency in some situations. Previously, passing audio through a send plugin to a return plugin always resulted in 1 buffer latency, i.e. 16, 32, 64 samples, whatever sushi was built with.

Now, if the send and return plugins are processed on the same core, and the send is on an earlier track than the return (lower track id). The audio will be sent with no latency. In other cases the send will still introduce 1 buffer of latency in the processing.

Note that, as before, multiple send plugins can send to a single return plugin instance and some of these sends can be zero latency while some are 1 buffer latency.

Vst3 Extensions

Sushi now exposes an extension interface that Vst3 plugins can implement to access features not available in the Vst3 API. The API is available here Vst3 extensions can be used with JUCE through the VST3ClientExtension interface

The Elk extension currently expose 2 features:

String Properties

These enable the plugin to expose any number of string parameters that can be set or retrieved from the gRPC interface or set to initial values in a json config file.
Note that string properties are accessed from non-realtime threads. There is an option to also enable Sushi to call a function in the audio thread, before calling process(), when properties are changed.

The strings do not need to be null terminated so can be used to pass arbitrary data.

Asynchronous work requests

Plugins can request non-realtime callbacks from an audio thread. This is very useful for delegating any work not suitable for doing in the audio thread to a background thread. Things like sample loading or interacting with the OS.

Plugins supply a callback that will be called in a background thread by Sushi and the return value from this callback will be passed back to Sushi in the audio thread in a later audio block. A unique id is generated for each request

See the inline documentation in the repository for more details.

Building the features

Sushi can be built with the existing SDK at GitHub - elk-audio/elkpi-sdk: Yocto cross-compiling toolchains for Elk on Raspberry Pi 4 or even on an Elk Device running a development image.

Note that, as twine is also updated, you need to build Sushi with the option SUSHI_BUILD_TWINE enabled. If you want to use ElkPy or ElkCpp to control sushi you also need to update those libraries on the device.

Note that all libraries mentioned above should be checked out from the develop branch!

Please ask if there’s anything that’s not clear or if you have any feedback!
Happy hacking!

1 Like