Table of Contents
This tutorial follows on from Tutorial: Create a basic Audio/MIDI plugin Part 1: Setting up, and will talk through starting from a clean project and ending up with a fully functioning, if somewhat simple, plug-in that can react to incoming MIDI notes.
Platforms: Windows, Mac OS X, Linux
Launch the Projucer and create a new audio plug-in project with the name TutorialPlugin. If you don't remember how to do that, please refer to Tutorial: Getting started with the Projucer.
A newly-created audio plug-in project contains two main classes:
PluginProcessor handles the audio and MIDI IO and processing logic, and
PluginEditor handles any on screen GUI controls or visualisations.
When passing information between these two it is best to consider the processor as the parent of the editor. There is only one plug-in processor whereas you can create multiple editors. Each editor has a reference to the processor such that it can edit or access information and parameters from the audio thread. It is the editor’s job to set and get information on this processor thread and not the other way around.
The main function we will be editing in the
PluginProcessor.cpp file is the
processBlock() method. This receives and produces both audio and MIDI data to the plug-in output. The main function we will change in the
PluginEditor.cpp file is the constructor, where we initialise and set up our window and GUI objects, and also the
paint() method where we can draw extra controls and custom GUI components.
The editor constructor currently has one method call —
setSize (400, 300) — which sets the size of our plug-in window. Let's make a smaller window of
(200, 200) for this simple application.
We will create a slider object to change the volume of MIDI messages as they come in.
Create a new Slider object in the Editor header file called
- The AudioProcessorEditor plays the same role in an Audio Plug-in that the main content component has in a standalone app. See Tutorial: The main content component.
We can set the properties of this slider with various functions in the editor constructor. We must also call
addAndMakeVisible (&midiVolume) to attach our slider to the editor. There are many different slider styles and parameters to use and experiment with in your own project. For this tutorial adjust the slider parameters such that your editor constructor looks like this:
JUCE windows have a method called
resized() that is called once at the initialisation of the window and every time the window is resized by the user (if resizing is enabled). This is a good place to set the size and position of our sliders (and other GUI components) so they can be positioned relative to the window bounds.
Lets also change the
"Hello World" text to
"Midi Volume" in the
paint() function and move it to the top. This function is where all custom shapes and GUI elements are drawn to the window.
- You can learn more about Components and their methods
resized()in Tutorial: The Graphics class and Tutorial: The Component class, parents, and children.
Running this program should create a plug-in that looks like this in the host editor:
We now have an control that we can adjust, but that doesn’t actually control anything. We need to intercept the incoming MIDI data and replace the note on volume with the volume of our slider, and this is done in the processor. In order to get the slider value to control the MIDI effect on the processor thread we need to create a new variable on the processor thread that we can use the slider to change.
Create a new public float variable called
noteOnVel in the processor class header. This is the variable that we will set with the slider.
We need to set this value whenever the slider is changed. To do this we use a slider listener callback function. Any class can inherit slider listener functionality but for the purposes of this tutorial we will add this functionality to the editor class.
- For a more in-depth description of listeners please see Tutorial: Listeners and broadcasters.
Add the inheritance and the default callback function so the editor class looks like this:
Now we add the slider listener to our volume slider in the editor constructor:
...and insert the listener function that sets our public processor volume variable:
We now have a slider that controls our variable in the processor class. We now need to use this processor variable to alter our MIDI data.
processBlock() method in the processor class receives and produces both MIDI and audio buffers in real time. We are going to iterate through the midi buffer to intercept signals of
noteOn type and set their velocity to the value of our slider.
The MIDI messages are all passed through this function. To alter the MIDI as it passes through we create a new MidiBuffer object called
processedMidi and append our modified MIDI signals to this new buffer before swapping it with the original at the end (this avoids direct modification problems). Remove the current code in the
processBlock() method (this handles the audio buffer, which we do not need for this tutorial) and replace it with the code below.
Run the plug-in in the host environment and you will see that all MIDI note on signals are coming through our plug-in have the value set with our slider. The
if() statement above can be also used to modify and apply various transformations and effects to other types of incoming MIDI signals. With these methods you can build more complex effects and GUIs.
- Experiment with other GUI components such as buttons and sliders, check the JUCE Demo example for a taste of JUCE’s capabilities, and refer back to the API documentation for more information.
- Generating audio using the incoming MIDI notes will be covered in a future tutorial (see Tutorial: Synthesiser using MIDI input). For now, please have a look at the
audio plugin demo, which is located in
After reading this tutorial, you should be able to:
- Create an audio plug-in with a basic GUI,
- Let your plug-in receive MIDI data.
Generated on Fri Jan 12 2018 09:51:15 for JUCE by 1.8.13