%% Host External Audio Plugin Tutorial (Parameter Mode)
% The following tutorial walks through the steps of loading and configuring an external audio plugin in parameter display mode.
%% 1. Load External Audio Plugin
% Use the loadAudioPlugin function to host the ReaDelay VST plugin. If the plugin is in your current folder, you can specify just the file name. Otherwise, you must specify the full path. In this example, the plugin is in the current folder.

hostedPlugin = loadAudioPlugin('readelay-standalone.dll');

%
% By default, the display mode is set to property. Set the DisplayMode property to Parameters for low-level interaction with the hosted plugin.

hostedPlugin.DisplayMode = 'Parameters'

%
% The first line displays the plugin type, plugin display name, and the number of input and output channels for the main audio processing algorithm of the plugin. If you are hosting a source plugin, the number of output channels and the default samples per frame are displayed.
% By default, only the first five parameters are displayed. To display all parameters of the hosted plugin, click See all 12 params.
% The table provides the parameter index, parameter name, normalized parameter value, displayed parameter value, and the displayed parameter value label.
%
% The normalized parameter value is always in the range [0,1] and generally corresponds to the position of a user interface (UI) widget in a DAW or the position of a MIDI control on a MIDI control surface. The parameter display value is related to the normalized parameter value by an unknown mapping internal to the plugin and typically reflects the value used internally by the plugin for processing.
%% 2. Set and Get Hosted Plugin Parameter Values
% You can use getParameter and setParameter to interact with the parameters of the hosted plugin. Using getParameter and setParameter is the programmatic equivalent of moving widgets in a UI or controls on a MIDI control surface. A typical DAW UI provides the parameter name, a visual representation of the normalized parameter value, the displayed parameter value, and the displayed parameter value label.
%
% For example, the Wet parameter of readelay-standalone.dll has a normalized parameter value of 1 and a display parameter value of +0.0. The Wet parameter might be displayed in a DAW as follows:
%
% With Audio Toolbox, you can use getParameter to return the normalized parameter value and additional information about a single hosted plugin parameter. You can specify which parameter to get by the parameter index.

parameterIndex = 1;
[normParamValue,paramInfo] = getParameter(hostedPlugin,parameterIndex)

%
% You can use setParameter to set a normalized parameter value of your hosted plugin. You can specify which parameter to set by its parameter index.

normParamValue = 0.5;
setParameter(hostedPlugin,parameterIndex,normParamValue)

%
% Setting the normalized parameter value to 0.5 is equivalent to setting the indicator to the center of a slider in a DAW.
%
% To verify the new normalized parameter value for Wet, use getParameter.

parameterIndex = 1;
[normParamValue,paramInfo] = getParameter(hostedPlugin,parameterIndex);

%
% The DisplayValue for the Wet parameter updates from +0.0 to -6.0 because you set the corresponding normalized parameter value. The relationship between the displayed value and the normalized value is determined by an unknown mapping that is internal to the hosted plugin.
%
%% 3. Use Hosted Plugin to Process Audio
% To process an audio signal with the hosted plugin, use process.

audioIn = [1,1];
audioOut = process(hostedPlugin,audioIn);

%
% Audio plugins are designed for variable-frame-based processing, meaning that you can call process with successive audio input frames of different lengths. The hosted plugin saves the internal states required for continuous processing. To process an audio signal read from a file and then written to your audio output device, place your hosted plugin in an audio stream loop. Use dsp.AudioFileReader and audioDeviceWriter objects as the input and output to your audio stream loop, respectively. Set the sample rate of the hosted plugin to the sample rate of the audio file by using setSampleRate.

fileReader = dsp.AudioFileReader('Counting-16-44p1-mono-15secs.wav');
sampleRate = fileReader.SampleRate;

deviceWriter = audioDeviceWriter('SampleRate',sampleRate);
setSampleRate(hostedPlugin,sampleRate);

while ~isDone(fileReader)
    audioIn = fileReader();
    
    % The hosted plugin requires a stereo input.
    stereoAudioIn = [audioIn,audioIn];
    
    x = process(hostedPlugin,stereoAudioIn);
    
    deviceWriter(x);
end

release(fileReader)
release(deviceWriter)

%
% You can modify parameters in the audio stream loop. To control the Wet parameter of your plugin in an audio stream loop, create an audioOscillator System object™. Use the fileReader, deviceWriter, and hostedPlugin objects you created previously to process the audio.

osc = audioOscillator('sine', ...
    'Frequency',10, ...
    'Amplitude',0.5, ...
    'DCOffset',0.5, ...
    'SamplesPerFrame',fileReader.SamplesPerFrame, ...
    'SampleRate',sampleRate);

while ~isDone(fileReader)
    audioIn = fileReader();
    
    controlSignal = osc();
    setParameter(hostedPlugin,1,controlSignal(1));
    
    stereoAudioIn = [audioIn,audioIn];
    x = process(hostedPlugin,stereoAudioIn);
    deviceWriter(x);
end

release(fileReader)
release(deviceWriter)

%
%% 4. Analyze Hosted Plugin
% You can use the Audio Toolbox measurement and visualization tools to display behavior information about your hosted plugin. To display the input and output of your hosted audio plugin, create a dsp.TimeScope object. Create a loudnessMeter object and use the 'EBU Mode' visualization to monitor loudness output by the hosted plugin. Use the fileReader, deviceWriter, osc, and hostedPlugin objects you created previously to process the audio.

scope = dsp.TimeScope( ...
    'SampleRate',sampleRate, ...
    'TimeSpanOverrunAction','Scroll', ...
    'TimeSpan',5, ...
    'BufferLength',5*2*sampleRate, ...
    'YLimits',[-1 1]);

loudMtr = loudnessMeter('SampleRate',sampleRate);
visualize(loudMtr)

while ~isDone(fileReader)
    audioIn = fileReader();
    
    controlSignal = osc();
    setParameter(hostedPlugin,1,controlSignal(1));
    
    stereoAudioIn = [audioIn,audioIn];
    x = process(hostedPlugin,stereoAudioIn);
    
    loudMtr(x);
    scope([x(:,1),audioIn(:,1)])
    
    deviceWriter(x);
end

%

release(fileReader)
release(deviceWriter)

%
% Copyright 2012-2018 The MathWorks, Inc.