Sensei - Standing in the way of control

As Elk is a complete platform on which you can build powerful audio processing devices quickly, it wouldn’t be complete without a way of connecting physical controls, such as buttons, knobs or interactive sensors, i.e pressure, distance or other types of sensors to the device. Usually these sensors are connected to ADCs and/or digital I/O pins, and their use requires a fair amount of low level programming in order to interface with and convert their raw output into a format usable for controlling audio plugins, be it MIDI, OSC, or other.

Sensei is the controller software in the Elk Audio OS, that enables you to easily connect physical controls to an Elk board, and use them to control the audio host Sushi, along with all the plugins it is hosting. Sensei supports a variety of controllers such as buttons, rotary encoders, LEDs, ribbon controllers and anything else that outputs an analog voltage like potentiometers, pressure sensors, etc. In addition, Sensei supports routing and basic clipping and scaling of values.

Controllers and sensors are defined declaratively in a json file, where the user specifies a list of hardware controllers, their types, which i/o pin(s) they are connected to, along with further parameters such as update rate, filtering and also clipping and scaling of the output range. Then Sensei handles the rest and allows you to output messages through one of its backends.

Sensei is of a modular design, and currently has 2 output backends: a terminal output that is mainly for debugging, and an OSC backend that can be used to control Sushi directly, or through a middleware “glue application”. More output backends can be added in the future.

A schematic view of where Sensei fits in an Elk device

On some Elk boards the I/O pins are managed by a microcontroller, in which case Sensei interfaces with them through a custom driver. On other boards, the pins are handled by the main CPU. In both cases Sensei abstracts away all the low-level details of interacting with GPIO pins into a simple interface so the developer doesn’t have to worry about them. It also ensures that config files are portable across different Elk boards.


A Sensei configuration file defines a list of sensors connected to the board and which pin(s) they are connected to. Each sensor is configured through a sensor type which defines its behaviour, and a hardware type which specifies what type of physical controller it represents.

Sensor types supported:

Currently supported hardware types are:

Support for more hardware types will be added in the future. If you need to connect a sensor or output device for which there is no native support, or for which there is no physical hardware type ready, you will have the possibility to do so by rebuilding Sensei with the open-source version of Elk.


The example below shows a Sensei setup with a potentiometer connected to an analog input pin and an LED connected to a digital output pin that can be turned on and off from an application interacting with Sensei.


 "backends" : [


     "id" : 0,

     "enabled": true,

     "raw_input_enabled": false,

     "type" : "osc",

     "host" : "localhost",

     "port" : 23023,

     "base_path" : "/sensors",

     "base_raw_input_path" : "/raw_input"



 "sensors" : [


     "id" : 1,

     "enabled": true,

     "name" : "LED 1",

     "sensor_type" : "digital_output_pin",

     "hardware" :


       "hardware_type" : "digital_output_pin",

       "pins" : [8]




     "id" : 23,

     "enabled": true,

     "name" : "Knob 1",

     "sensor_type" : "analog_input",

     "mode" : "on_value_changed",

     "hardware" :


       "hardware_type" : "analog_input_pin",

       "pins" : [2],

       "delta_ticks" : 1,

       "adc_resolution" : 8,

       "filter_time_constant" : 0.01





In use

Sensei can be used to directly control Sushi over OSC, but the most common use case is to have an intermediary Main app or “glue program” between Sushi and Sensei, that maps to parameters and encapsulates some simple logic. For instance, many devices have multi-function controls that can control different parameters depending on the current settings. In most cases such logic would be best implemented in the glue program

Want to go into more detail. Please check out the documentation or one of our examples to see a real life Sensei configuration could look like.

If you have further questions, Feel free visit our forum, let us know your thoughts here in the comments or write us at