Introduction on how to use pyo inside a Juce audio plugin.
========================================================== 

To use pyo inside a Juce audio plugin, first you need a working 
install of pyo on your system. After installing pyo, you can move 
on and create a Juce audio plugin project.

------------------------------------------------------------------------------
Step 1 - Create an Audio Plug-In project with the Introjucer. 

------------------------------------------------------------------------------
Step 2 - Add pyo files to your project. You only need to copy 
these files in your project "Source" folder:

- from this folder:
PyoClass.cpp
PyoClass.h

- from the folder "embedded":
m_pyo.h

------------------------------------------------------------------------------
Step 3 - Make sure that your project includes flags for compiling 
and linking against Python. Within the Introjucer, you can set extra
flags in the "Config" tab. For example, on linux, if you select "Linux
Makefile", you can add extra compiler and linker flags. Add these in
the specific fields:

Extra linker flags : `python-config --ldflags`
Extra compiler flags : `python-config --cflags`

------------------------------------------------------------------------------
Step 4 - Make sure that your project links to the Steinberg's VST SDK.
VST SDK can be freely downloaded from Steinberg web site:
http://www.steinberg.net/en/company/developers/
Enter the path in the field "VST Folder" in the export configuration.

------------------------------------------------------------------------------
Step 5 - Create a python file, named "stereoDelay.py", with these lines in 
it:

# Retrieve the stereo input of the plugin.
st_input = Input([0,1])
# Parameters to change.
dtime = SigTo(.5, 0.05, .5)
feed = SigTo(.5, 0.05, .5)
# Simple process. Stereo delay -> reverb.
st_delay = SmoothDelay(st_input, delay=dtime, feedback=feed)
st_rev = WGVerb(st_delay, feedback=0.8, cutoff=4000, bal=0.25).out()

Save "stereoDelay.py" in the "Source" folder, add it to the project in the
Introjucer and ensure that the option "Add to Binary Resources" is checked.
Save your project. This should add two files, "BinaryData.h" and 
"BinaryData.cpp", in the "JuceLibraryCode" folder.
 
------------------------------------------------------------------------------
Step 6 - Edit Source/PluginProcessor.h

- Include PyoClass definition:

#include "PyoClass.h"

- Add a Pyo object to the public attributes of the XXXAudioProcessor class:

    Pyo pyo;

------------------------------------------------------------------------------
Step 7 - Edit Source/PluginProcessor.cpp

- Add these line to XXXAudioProcessor::prepareToPlay method:

    pyo.setup(getNumOutputChannels(), samplesPerBlock, sampleRate);
    pyo.exec(BinaryData::stereoDelay_py);

- Replace the content of XXXAudioProcessor::processBlock method with
this line:

    pyo.process(buffer);

------------------------------------------------------------------------------
Here you go! Compile, Run and Enjoy!

Adding GUI controls to your plugin
==================================

Now, we will add two sliders to control the delay time and the feedback
of our process.

------------------------------------------------------------------------------
Step 8 - Edit Source/PluginEditor.h

- Add the inheritance to Slider::Listener to your XXXAudioProcessorEditor
class definition:
    
class XXXAudioProcessorEditor  : public AudioProcessorEditor, 
                                 private Slider::Listener
 
- Add the default callback function in the public attributes of the class:
    
    void sliderValueChanged(Slider* slider) override;

- Create two sliders in the public attributes of the class:
    
    Slider p1;
    Slider p2;

------------------------------------------------------------------------------
Step 9 - Edit Source/PluginEditor.cpp

- Set the sliders properties in the editor constructor function named
XXXAudioProcessorEditor::XXXAudioProcessorEditor (this is the first function
in the PluginEditor.cpp file). Add these lines at the end of the function:
    
    // these define the parameters of our slider object
    p1.setSliderStyle(Slider::LinearBarVertical);
    p1.setRange(0.0, 1.0, 0.01);
    p1.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
    p1.setPopupDisplayEnabled(true, this);
    p1.setTextValueSuffix(" Delay Time");
    p1.setValue(0.5);
    p1.addListener(this);
    // this function adds the slider to the editor
    addAndMakeVisible(&p1);

    p2.setSliderStyle(Slider::LinearBarVertical);
    p2.setRange(0.0, 1.0, 0.01);
    p2.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
    p2.setPopupDisplayEnabled(true, this);
    p2.setTextValueSuffix(" Delay Feedback");
    p2.setValue(0.5);
    p2.addListener(this);
    addAndMakeVisible(&p2);

- Set the size and position of the sliders. Add these lines in 
XXXAudioProcessorEditor::resized() function:
    
    p1.setBounds(40, 30, 20, getHeight() - 60);
    p2.setBounds(70, 30, 20, getHeight() - 60);

------------------------------------------------------------------------------
Step 10 - Connect the sliders to the audio proces

- At the end of the file PluginEditor.cpp, create the slider's callback 
function which will pass the values to the audio processing objects:
    
void XXXAudioProcessorEditor::sliderValueChanged (Slider* slider)
{
    processor.pyo.value("dtime", p1.getValue());
    processor.pyo.value("feed", p2.getValue());
}

------------------------------------------------------------------------------
That's it! Compile and Run...

Documentation
=============

For a complete description of functions used to communicate with the pyo 
embedded processes, see documentation comments in the file PyoClass.cpp.


(c) 2015 - belangeo
