The Elk Audio OS consists of many different parts. In this post I will focus on what we call Sushi, the DAW that is at the core of audio and midi processing in the Elk Audio OS. I hope you find it interesting!
Sushi – Main features
Sushi is a track-based, headless Digital Audio Workstation. It works as a plugin host, supporting multiple plugin standards, features advanced audio and midi routing, simple scripting setup and is written to ensure high performance and stability under low latency conditions. It can be controlled through MIDI, OSC, or a gRPC interface.
Sushi shares the same basic architecture with most common daws like Cubase or Ableton Live, having an unlimited number of parallel channels. Each track supporting mono, stereo or up to 64 audio channels and as many plugins as the CPU can handle. Pure MIDI tracks are also supported, for instance outputting MIDI from an arpeggiator or step sequencer to an external device.
There is also a multibus track mode with which a multichannel track can have multiple stereo outputs, each with their own individual gain and panning controls, which in turn can be routed to any audio output. Useful for multi bus plugins. Sushi also features aux sends and corresponding return tracks for effects processing.
Sushi supports a number of protocols and technologies for controlling and synching with external sources and devices: MIDI, OSC, Ableton Link, gRPC.
MIDI input and output is supported through ALSA. This enables integration with any class compliant midi device, like USB MIDI keyboards or controllers. A flexible routing system allows you to route MIDI based on channels to any track. MIDI can be freely routed to tracks and MIDI Program Change and Control Change messages can be mapped to plugins and parameters respectively. MIDI data can also be processed or generated by plugins like sequencers.
Sushi also supports Open Sound Control – OSC. And can both send OSC updates and receive notes and parameter changes through OSC.
Another cool feature is tempo sync over Ableton Link, which enables you to seamlessly tempo sync Sushi with other devices over wifi. This works with computers running Ableton Live or any Link enabled mobile app like Reason Compact or Korg Gadget.
As Sushi is a headless host, and intended for use in an embedded device, it does not feature a graphical user interface. In its place is a gRPC interface that can be used for controlling all aspects of Sushi and hosted plugins. gRPC has bindings for most common programming languages, this gives total freedom to customise the behaviour and write a complete GUI for Sushi in more or less any GUI framework of choice and account for multiple use cases.
For some applications, like the upcoming Smart Multiamp from DV Mark, user interactions will come from both front panel knobs and a handheld device, i.e. a smartphone or tablet. In that case, an app can use the gRPC interface to control Sushi. Other ELK devices could feature a built-in screen. In that case the GUI will run on the same CPU as Sushi, though in a different process. But as mentioned before, the GUI can be built in Python or any other programming language of choice. The dual kernel architecture of ELK will guarantee that the graphics rendering will never interfere with the audio dsp processing.
Sushi was built to work in perfect sync with Raspa, our proprietary low-latency audio framework. But Sushi also has built-in support for Jack, as well as an offline mode where audio is read from and written to file. The latter can be used for testing in an environment that lacks audio codecs and for evaluating systems in a very early stage. It has also proven to be very useful in debugging.
The ability to run Sushi with Jack, the most common audio framework on Linux, makes it possible to run on almost any Linux system. While it doesn’t give the same ultra low latency as running it with Raspa on an ELK system. It does make it incredibly easy to test and develop plugins and setups for ELK on a standard Linux machine. In fact, almost all of the development of Sushi has been done on standard Linux machines.
When running with Raspa, Sushi is limited to the number of inputs and outputs supported by the physical hardware. While when running with Jack, Sushi exposes 8 input ports and 8 output ports that can then be freely routed to physical outputs or inputs, or other Jack software.
Most of the initial setup of Sushi is done through a JSON configuration file. In this it’s possible to specify the number of tracks to use, their channel setup (mono, stereo, multichannel), the plugins on the track, audio input and output routing, MIDI routing, which plugin parameters map to Control Change messages, and so on. See below for a very simple example for how to set up a synth plugin with MIDI-mapped parameters.
Plugin format support
Sushi supports and can load plugins built in Steinberg’s VST 2.4 and VST 3.6 formats as well as Rack Extensions from Propellerheads. In order to load plugins in Sushi, they need to be compiled for the system intended. Note that it is not possible to take an existing Windows, macOS, or even native Linux plugin binary and load it in ELK. That will not work. Though if the plugins are well written from the start, porting them to ELK should be a rather straightforward process of recompiling the plugins using our SDK.
Sushi can run its audio processing single threaded but also has built in multithreading support to spread the audio processing over multiple cores, depending on the type of system it is running on. For developers that wish to utilise multithreading within a plugin, we have developed a small threading utility library that works with ELK and Sushi, called Twine. This library also includes a few utility functions and wrappers for certain system calls like timers to abstract away some of the limitations of the dual kernel setup.