# Design User Interface for Audio Plugin

Audio plugins enable you to tune parameters of a processing algorithm while streaming audio in real time. To enhance usability, you can define a custom user interface (UI) that maps parameters to intuitively designed and positioned controls. You can use `audioPluginInterface`, `audioPluginParameter`, and `audioPluginGridLayout` to define the custom UI. You can interact with the custom UI in MATLAB® using `parameterTuner`, or deploy the plugin with a custom UI to a digital audio workstation (DAW). This tutorial walks through key design capabilities of audio plugins by sequentially enhancing a basic audio plugin UI.

### Default User Interface

The `equalizerV1` audio plugin enables you to tune the gains and center frequencies of a three-band equalizer, tune the overall volume, and toggle between enabled and disabled states.

```classdef equalizerV1 < audioPlugin properties GainLow = 0 FreqLow = sqrt(20*500) GainMid = 0 FreqMid = sqrt(500*3e3) GainHigh = 0 FreqHigh = sqrt(3e3*20e3) Volume = 1 Enable = true end properties (Constant) PluginInterface = audioPluginInterface( ... audioPluginParameter('GainLow', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}), ... audioPluginParameter('FreqLow', ... 'Label','Hz', ... 'Mapping',{'log',20,500}), ... audioPluginParameter('GainMid', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}), ... audioPluginParameter('FreqMid', ... 'Label','Hz', ... 'Mapping',{'log',500,3e3}), ... audioPluginParameter('GainHigh', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}), ... audioPluginParameter('FreqHigh', ... 'Label','Hz', ... 'Mapping',{'log',3e3,20e3}), ... audioPluginParameter('Volume', ... 'Mapping',{'lin',0,2}), ... audioPluginParameter('Enable')) end properties (Access = private) mPEQ end methods function obj = equalizerV1 obj.mPEQ = multibandParametricEQ('HasHighpassFilter',false, ... 'HasLowShelfFilter',false,'HasHighShelfFilter',false, ... 'HasLowpassFilter',false,'Oversample',false,'NumEQBands',3, ... 'EQOrder',2); end function y = process(obj, x) if obj.Enable y = step(obj.mPEQ,x); y = y*obj.Volume; else y = x; end end function reset(obj) obj.mPEQ.SampleRate = getSampleRate(obj); reset(obj.mPEQ); end function set.FreqLow(obj,val) obj.FreqLow = val; obj.mPEQ.Frequencies(1) = val; %#ok<*MCSUP> end function set.GainLow(obj,val) obj.GainLow = val; obj.mPEQ.PeakGains(1) = val; end function set.FreqMid(obj,val) obj.FreqMid = val; obj.mPEQ.Frequencies(2) = val; end function set.GainMid(obj,val) obj.GainMid = val; obj.mPEQ.PeakGains(2) = val; end function set.FreqHigh(obj,val) obj.FreqHigh = val; obj.mPEQ.Frequencies(3) = val; end function set.GainHigh(obj,val) obj.GainHigh = val; obj.mPEQ.PeakGains(3) = val; end end end ```

Call `parameterTuner` to visualize the default UI of the audio plugin.

`parameterTuner(equalizerV1)`

### Control Style and Layout

To define the UI grid, add `audioPluginGridLayout` to the `audioPluginInterface`. You can specify the number, size, spacing, and border of cells in the UI grid. In this example, specify RowHeight as `[20,20,160,20,100]` and ColumnWidth as `[100,100,100,50,150]`. This creates the following UI grid:

To define the UI control style, update the `audioPluginParameter` definition of each parameter to include the Style and Layout name-value pairs. `Style` defines the type of control (rotary knob, slider, or switch, for example). `Layout` defines which cells the controls occupy on the UI grid. You can specify `Layout` as the [row, column] of the grid to occupy, or as the [upper, left; lower, right] of the group of cells to occupy. By default, control display names are also displayed and occupy their own cells on the UI grid. The cells they occupy depend on the DisplayNameLocation name-value pair.

The commented arrows indicate the difference between `equalizerV1` and `equalzierV2`.

```classdef equalizerV2 < audioPlugin ... % omited for example purposes properties (Constant) PluginInterface = audioPluginInterface( ... audioPluginParameter('GainLow', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... %<-- 'Layout',[2,1;4,1], ... %<-- 'DisplayName','Low','DisplayNameLocation','Above'), ... %<-- audioPluginParameter('FreqLow', ... 'Label','Hz', ... 'Mapping',{'log',20,500}, ... 'Style','rotaryknob', ... %<-- 'Layout',[5,1], ... %<-- 'DisplayNameLocation','None'), ... %<-- audioPluginParameter('GainMid', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... %<-- 'Layout',[2,2;4,2], ... %<-- 'DisplayNameLocation','None'), ... %<-- audioPluginParameter('FreqMid', ... 'Label','Hz', ... 'Mapping',{'log',500,3e3}, ... 'Style','rotaryknob', ... %<-- 'Layout',[5,2], ... %<-- 'DisplayNameLocation','None'), ... %<-- audioPluginParameter('GainHigh', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... %<-- 'Layout',[2,3;4,3], ... %<-- 'DisplayName','High','DisplayNameLocation','Above'), ... %<-- audioPluginParameter('FreqHigh', ... 'Label','Hz', ... 'Mapping',{'log',3e3,20e3}, ... 'Style','rotaryknob', ... %<-- 'Layout',[5,3], ... %<-- 'DisplayNameLocation','None'), ... %<-- audioPluginParameter('Volume', ... 'Mapping',{'lin',0,2}, ... 'Style','rotaryknob', ... %<-- 'Layout',[3,5], ... %<-- 'DisplayNameLocation','Above'), ... %<-- audioPluginParameter('Enable', ... 'Style','vtoggle', ... %<-- 'Layout',[5,5], ... %<-- 'DisplayNameLocation','None'), ... %<-- ... audioPluginGridLayout( ... %<-- 'RowHeight',[20,20,160,20,100], ... %<-- 'ColumnWidth',[100,100,100,50,150]) %<-- end ... % omitted for example purposes end ```

The `Layout` and `DisplayNameLocation` defined in the `audioPluginParameter`s maps the respective parameters to the control grid as follows:

Call `parameterTuner` to visualize the UI of `equalizerV2`.

`parameterTuner(equalizerV2)`

### Background Image and Color

To customize the background of your UI, specify BackgroundImage and BackgroundColor in `audioPluginInterface`.

The `BackgroundColor` can be specified as a short or long color name string or as an RBG triplet. When you specify `BackgroundColor`, the color is applied to all space on the UI except space occupied by controls or a `BackgroundImage`. If the control or background image includes a transparency, then the background color shows through the transparency.

The `BackgroundImage` can be specified as a PNG, GIF, or JPG file. The image is applied to the UI grid by aligning the top left corners of the UI grid and image. If the image is larger than the UI grid size defined in `audioPluginGridLayout`, then the image is clipped to the UI grid size. The background image is not resized. If the image is smaller than the UI grid, then unoccupied regions of the UI grid are treated as transparent.

In this example, you increase the padding around the perimeter of the grid to create space for the MathWorks® logo. You can calculate the total width of the UI grid as the sum of all column widths plus the left and right padding plus the column spacing (the default column spacing of `10` pixels is used in this example): $\left(100+100+100+50+150\right)+\left(20+20\right)+\left(4×10\right)=580$. The total height of the UI grid is the sum of all row heights plus the top and bottom padding plus the row spacing (the default row spacing of 10 pixels is used in this example):$\left(20+20+160+20+100\right)+\left(20+120\right)+\left(4×10\right)=500.$ To locate the logo at the bottom of the UI grid, use a 580-by-500 image:

```classdef equalizerV3 < audioPlugin ... % omitted for example purposes properties (Constant) PluginInterface = audioPluginInterface( ... audioPluginParameter('GainLow', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,1;4,1], ... 'DisplayName','Low','DisplayNameLocation','Above'), ... audioPluginParameter('FreqLow', ... 'Label','Hz', ... 'Mapping',{'log',20,500}, ... 'Style','rotaryknob', ... 'Layout',[5,1], ... 'DisplayNameLocation','None'), ... audioPluginParameter('GainMid', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,2;4,2], ... 'DisplayNameLocation','None'), ... audioPluginParameter('FreqMid', ... 'Label','Hz', ... 'Mapping',{'log',500,3e3}, ... 'Style','rotaryknob', ... 'Layout',[5,2], ... 'DisplayNameLocation','None'), ... audioPluginParameter('GainHigh', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,3;4,3], ... 'DisplayName','High','DisplayNameLocation','Above'), ... audioPluginParameter('FreqHigh', ... 'Label','Hz', ... 'Mapping',{'log',3e3,20e3}, ... 'Style','rotaryknob', ... 'Layout',[5,3], ... 'DisplayNameLocation','None'), ... audioPluginParameter('Volume', ... 'DisplayName','Volume', ... 'Mapping',{'lin',0,2}, ... 'Style','rotaryknob', ... 'Layout',[3,5], ... 'DisplayNameLocation','Above'), ... audioPluginParameter('Enable', ... 'Style','vtoggle', ... 'Layout',[5,5], ... 'DisplayNameLocation','None'), ... ... audioPluginGridLayout( ... 'RowHeight',[20,20,160,20,100], ... 'ColumnWidth',[100,100,100,50,150], ... 'Padding',[20,120,20,20]), ... %<-- ... 'BackgroundImage','background.png', ... %<-- 'BackgroundColor',[210/255,210/255,210/255]) %<-- end ... % omited for example purposes end ```

Call `parameterTuner` to visualize the UI of `equalizerV3`.

`parameterTuner(equalizerV3)`

### Custom Control Filmstrips

To use custom filmstrips, specify the Filmstrip and FilmstripFrameSize name-value pairs in `audioPluginParameter`. The filmstrip can be a PNG, GIF, or JPG file, and should consist of frames placed end-to-end either vertically or horizontally. The filmstrip is mapped to the control's range so that the corresponding filmstrip frame is displayed on the plugin UI as you tune parameters. In this example, specify a two-frame filmstrip for the `Enable` parameter. As a best practice, the size of each frame of the film strip should equal the size of the region occupied by the parameter. The `Enable` parameter occupies one cell that is 150-by-100 pixels. To create a vertical filmstrip where each frame is 150-by-100, make the total filmstrip size 150-by-200 and set `FilmstripFrameSize` to `[150,100]`. The filmstrip used in this example contains the frame corresponding to the off position first, then the on position:

```classdef equalizerV4 < audioPlugin ... % omitted for example purposes properties (Constant) PluginInterface = audioPluginInterface( ... audioPluginParameter('GainLow', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,1;4,1], ... 'DisplayName','Low','DisplayNameLocation','Above'), ... audioPluginParameter('FreqLow', ... 'Label','Hz', ... 'Mapping',{'log',20,500}, ... 'Style','rotaryknob', ... 'Layout',[5,1], ... 'DisplayNameLocation','None'), ... audioPluginParameter('GainMid', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,2;4,2], ... 'DisplayNameLocation','None'), ... audioPluginParameter('FreqMid', ... 'Label','Hz', ... 'Mapping',{'log',500,3e3}, ... 'Style','rotaryknob', ... 'Layout',[5,2], ... 'DisplayNameLocation','None'), ... audioPluginParameter('GainHigh', ... 'Label','dB', ... 'Mapping',{'lin',-20,20}, ... 'Style','vslider', ... 'Layout',[2,3;4,3], ... 'DisplayName','High','DisplayNameLocation','Above'), ... audioPluginParameter('FreqHigh', ... 'Label','Hz', ... 'Mapping',{'log',3e3,20e3}, ... 'Style','rotaryknob', ... 'Layout',[5,3], ... 'DisplayNameLocation','None'), ... audioPluginParameter('Volume', ... 'Mapping',{'lin',0,2}, ... 'Style','rotaryknob', ... 'Layout',[3,5], ... 'DisplayNameLocation','Above'), ... audioPluginParameter('Enable', ... 'Style','vtoggle', ... 'Layout',[5,5], ... 'DisplayNameLocation','None', ... 'Filmstrip','vtoggle.png', ... %<-- 'FilmstripFrameSize',[150,100]), ... %<-- ... audioPluginGridLayout( ... 'RowHeight',[20,20,160,20,100], ... 'ColumnWidth',[100,100,100,50,150], ... 'Padding',[20,120,20,20]), ... ... 'BackgroundImage','background.png', ... 'BackgroundColor',[210/255,210/255,210/255]) end ... % omitted for example purposes end ```

Filmstrips are not supported by `parameterTuner`. To see the custom plugin UI, you must deploy the plugin to a DAW. Use `generateAudioPlugin` to create a VST plugin.

`generateAudioPlugin equalizerV4`
```....... ```

In this example, the plugin was opened in REAPER. A screenshot of the UI in REAPER is displayed below.