Main Content

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.

To learn more about audio plugins in general, see Audio Plugins in MATLAB.

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 audioPluginParameters 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. See ColorSpec (Color Specification) for details. 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): (100+100+100+50+150)+(20+20)+(4×10)=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):(20+20+160+20+100)+(20+120)+(4×10)=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.

Related Topics

See Also

| | | | |