JUCE 6 Tutorial 07 - Creating Parameters with the AudioProcessorValueTreeState Class (Pt 1 of 2)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up everybody i'd like to welcome you to another juice tutorial and in this tutorial we're going to talk about how we're going to be able to connect our visual objects that the user sees on the user interface so things like sliders and buttons to the actual data that happens underneath in our plug-in processor so if you're not sure what i'm talking about be sure to check out my previous tutorial where i talk about basic plug-in architecture and i'm going to break this tutorial down into two parts in this first part we're going to be talking about the processor side and so as i was saying before we're going we have pieces of data that uh that are parameters that we want the user to be able to control so if we have a dsp algorithm that let's say that is a delay and that we want to have something where we're going to be able to turn up and down the amount of delay then we're going to have two pieces of that component we're going to have the visual piece which is going to be some sort of dial or some sort of slider then we're going to have the actual piece of data which is going to be some sort of number that's going to live in the processor that we're going to be able to control with the slider so there are a few ways that this can actually be done and i'm gonna the way that i'm gonna show you is not the easiest way but it is what i think is the best way and this is using a class called the audio processor value tree state so there are a few aspects of this that are a little bit more towards the intermediate uh level of c plus and if you don't understand uh what's happening just follow along and uh also reference some of the parts that you don't understand and i promise that once you do this over time things will start to make sense so before we get started be sure to join our audio programmer community over at the audioprogrammer.com forward slash community is a great place where if you're having problems understanding some of these concepts you can ask questions with other people that are also audio developers and we have audio developers ranging from teenagers typing their first lines of code all the way up to professionals working at some of the biggest companies in the world and everything in between so uh so yeah come join us everybody is welcome it's free the audio programmer dot com forward slash community and if you'd like to see more tutorials like this be sure to check out our patreon where you can support us on patreon.com forward slash the audio programmer so let's go ahead and get started at the moment i have a plugin template is completely blank and i'm in the pluginprocessor.c so i'm going to go to the header file and now what i'm going to do is i'm going to open up my web browser and i'm just going to go to the juice api and i can give you the link to that below and so i'd like to show people exactly where i'm getting these methods and these things from and this class that we're looking for today is called the audio processor value tree state and we see it right here audio processor value tree state and uh so this is a this is a class this is a this is a a thing that can be very confusing for people especially if you're first starting out and uh hopefully this will be a very straightforward almost like a hello world of uh actually being able to set this up okay so i'm just gonna uh this is uh what is actually going to hold our parameters so as i said before uh we have these visual these visual objects uh that are like sliders and buttons and we have this data so if we have a button that we're pressing and uh that we might have uh the actual button that is living in the editor and then that's going to connect to a piece of data that's going to be in the processor where when the button is off might be a zero and when the button is on it might be a one for on so it might be a boolean value that's uh that's connected to this button okay this for this particular one we'll do a slider so uh so what we'll do is we're going to uh create an audio processor value tree state object and this object is actually what holds all of these parameters so everything that we want the user to be able to modify will actually be sitting as parameters in this audio processor value tree state so that's what we're going to do first thing that we're going to do is we're going to create a audio processor value tree state object so as you know we have to precede all juice objects with the namespace juice then it's just audio processor value tree state i'll call this ap vts and so now we've created our object now if we go back to our documentation what we will see is if we scroll down here to our constructors we'll see that there are two different types of constructors that we can actually call actually there's one because this one says this constructor is discouraged and will be deprecated in a future version of juice use the other one so there's only one real constructor so what that means is that on initialization when we initialize this audio processor value tree state object that we actually have to give it these arguments okay so because of that we'll have to use an initializer list to actually be able to do that and i'll show you how to do that in just a moment um i'm going to call your attention to the arguments that we need to give it uh so the first one is the audio process is an audio processor object and it says processor to connect to so if we take a look at our plug-in processor class we see that test audio processor which is our plug-in processor inherits from juice audio processor so test audio processor is a juice audio processor so that's what we that's the argument that we're going to put in for this first parameter we're not going to worry about an undo manager for this tutorial then we have this const identifier and value tree type so this is just a string that we can give where we can give the actual value tree a name and we'll just call this something like parameters and then we have this last one which is called parameter layout and this is the part that actually confuses a lot of people and it can be quite confusing if you've never seen this yourself being done before so if we just open this in a new tab then what we will see is that it says a class to contain a set of ranged audio parameters an audio processor parameter groups containing ranged audio parameters so that sounds like a mouthful it sounds quite complicated but really all it means is as i said before the the plugin is going to have some sort of parameters some sort of things you can turn off turn on and some things where you can control the range of them and that this parameter layout actually just holds the list of those things and tells it uh what the name of those parameters are and what the ranges of those are so that's all that this is and what we need to do is we're going to create a method where we're actually going to return a vector of uh of our parameters okay so it's actually just going to return this vector that's going to contain all of our parameters and if you're not familiar with a vector it holds uh it's basically a container that will hold uh what you tell it to in this case our parameters so the first thing that we're going to do uh our second thing we've already created our audio processor value tree state object is we're going to create a function and the return type of this function is going to be a juice audio processor value tree state and then parameter layout and that's that's the type of so when we get done calling this function it's going to return us this parameter layout and that's what we are going to use in our as an argument in when we're initializing the audio processor value tree state so basically what we're saying is we wanted to connect to this processor we don't want to worry about an undo manager the name of the uh this value tree is going to be called parameters and here's a list of the parameters that we want you to control so that's all it is so this function a great name for it might be something like create parameters and so we're going to declare it here and now we're going to go to our cpp and we are going to actually give it its uh implement it here so we got juice audio processor value tree state parameter layout and then we need to name the class that we're in so which is test audio processor i'll just copy it here save us a bit of time and then we called it create parameters okay and now we have our function here and oh i think i spelled this wrong parameters let me make sure i've got param parameters so there we are and now what we need to do we know that uh so as i was saying to you before that uh what we need to do is we're going to create a vector which is going to be a uh that's going to return this object type called a parameter layout at the very end and so i'm going to show you how to do this so this is going to be a stud vector and this is going to be a vector of stood unique pointers of and this gets a little bit complicated so i believe it's ranged audio parameters and we will just call this vector programs okay so that's that's quite a bit that's that's quite a bit to unload if you're first starting out but if you're not sure what's happening there just copy what copy what i see there and be sure to look up the uh the reference for these i'll actually put some links below so you can check them out uh on what these actually are but these are pointers of ranged audio parameters the parameters are just the parameters all the stuff that we want the user to be able to modify and plug in and it's a vector of these so it's a list of these ranged audio parameters now what we need to do and we we have a couple different types of ranged audio parameters that we can call so i'm going to leave this documentation i'm going to start a new tab and what we will do is we will go to the ranged audio parameter class and what we see here going in here is that we have an inheritance diagram here that shows all of our different types of ranged audio parameters so we have an audio parameter bull so that was like the button i was telling you about earlier where we have something that turns on and off we have an audio parameter choice so maybe that's a filter high pass low pass band pass so that's audio parameter choice audio parameter float which would be something between zero point something and whatever uh like a floating point number they have an audio parameter end which is obviously an int so in this particular example we'll just use an audio parameter float so we can see that all of these are different types of ranged audio parameters so i can actually just click here to go into audio parameter float and then we will see going in here that we have two different types of constructors that we can call we've got this really super long one that we can call i'm going to opt for the easier one here in this situation because i just want to give you the basics okay so this is going to be an audio parameter float that we're going to create so since we're in a vector called params we need to use the pushback method to add another uh another element to the end of our vector so we'll say params.pushback now since it's a unique pointer what we need to do is we need to actually allocate memory uh for this pointer we can do that using stood make unique and this is going to be a juice audio parameter float and remember that this uh this actually works because audio parameter float is a type of ranged audio parameter and in here we're going to put our arguments so that's the initialization arguments so i'm just going to copy these here the the thing that's kind of a pain about a about doing a pointer is that you have to actually kind of copy and paste these in it won't auto complete them for you so the first thing is the parameter id so the parameter id is a string that we will be able to anytime that we want to go back and grab this parameter this is the name that we're going to refer to so in this one i will just call it let's just call it gain right and then we will give it a name so uh i think the convention is that the first that the parameter id is all in all caps and then the uh actual name is just a first letter as a cap and then the all the other letters lower case so this is what you'll actually see in a daw when you actually uh when you actually open up the plugin in a daw it'll be called gain like this now we want to just give it a minimum value we'll just keep it simple and we'll say that we want it to be 0.0 and then i will put enough there just to make sure that it stays as a float okay make sure that it's not a zero like that okay because that's an int okay we don't want it to be an end we want it to be a float and that sounds like a very small difference but when you're actually doing dsp and things like that that actually makes a big difference okay so uh because it will cast things to it'll sometimes cast uh your what you think is a float back to an int that's not what you want now we've got a max value and we'll just make the max value one and let's say that we want a default value so this is the value that it starts off at and i will just make that 0.5 okay so we'll just make one parameter for this one and now what we want to do is we want to return this vector so the way that we would do this is return params dot begin rams dot end like that okay and that will give us our parameter layout so now that is fine and now what we want to do is we want to go we see that we're getting an error here and so you will you will see this if you haven't initialized something correctly and i'll show you this very quickly so sometimes you'll see an error that says something like constructor for test audio processor must explicitly initialize the member ap vts which does not have a default constructor okay sounds like a lot but let's break down what that actually means okay so must explicitly initialize the member apvts okay apvts is our audio processor value tree state object that we've created okay and what's it saying that the problem is it's saying that the problem is that it does not have a default constructor default constructor means that when we go back to audio processor value tree state and we look in our documentation we don't see a constructor that doesn't have any arguments right so what it's saying is that in order to initialize this we need to give it some arguments we need to tell it we need to give it these arguments in order to actually do that and so that's what we're going to do here so the way to do this is using what's called an initializer list and an initializer list is uh some is what's been uh it's already been started for us so basically what that means is that when this constructor calls before it goes into the body it's going to initialize uh any objects that we put in here so sometimes you have to use an initializer list to actually initialize these objects before it calls into the body of the constructor you can't actually initialize it in the body of the constructor so what we're going to do here and this can be a little bit confusing because you have some macros here that and some kind of conditionals that are being called that i'm not going to get into but uh what so it could be a little bit difficult to discern okay where do i actually need to put this but it's just at the end of this little parentheses right here okay and so i will just do that and it's a comma not a semicolon and here i will say apvts and then i need to use this constructor which is the processor so this is a reference to the processor that we want to connect to okay and the processor that we want to connect to is the processor that we're in right now so we can use the keyword this okay which is actually a pointer to our uh to the this instantiation of the class that we're in right now so what we need to do is we actually need to dereference the pointer using the star operator here okay so that's how we dereference that pointer and now we have a pointer to an undo manager to use we're not using an undo manager so we could just make this null pointer then as we said before we have this identifier type which is essentially a string that we're going to call the value tree and i'll just call this parameters and then we have this parameter layout object that we need to call and that is once again the list of our actual parameters that we want to have in this plugin and this and this is where i can call create parameters and i can do that because create parameters the method actually returns a parameter layout object okay so that's how that's why that works and what i could do is i could try to build here just make sure that this actually all works properly and as i was saying before if you're having problems or issues getting this to work properly be sure to check out our community over at the audioprogrammer.com forward slash community and if you like tutorials like this be sure to check out our patreon on patreon.com forward slash the audio programmer so here we are we're linking and we see this build that succeeded so we don't see anything at the moment so it says build succeeded this error isn't actually an error uh and i'll prove it again by just in that it says build succeeded so that's erroneous and um what when you build a plug-in you'll see that you actually don't see anything okay nothing nothing actually happens okay that's because we need to open up the plug-in in the host and i'll show you how to do that in a future tutorial so that's really it for this tutorial and i'm going to go over the actual editor side and how to connect the editor to what we've just created in the audio processor with the audio processor value tree state and i'm going to do that in the next tutorial be sure to like and subscribe if you found this tutorial helpful and i'll see you next time
Info
Channel: The Audio Programmer
Views: 3,669
Rating: undefined out of 5
Keywords: audio programming, creative coding, audio coding, creative programming, digital signal processing, dsp, plugins, vst, software development, ableton, max msp, c++, sample rate, bit depth, nyquist theorem, juce framework, tutorial, beginner, easy, games development, games programming, basics, openFrameworks, open Frameworks, ofx, Maxim, Maximilian, parameters, audioprocessorvaluetreestate
Id: nkQPsYOdIrk
Channel Id: undefined
Length: 21min 23sec (1283 seconds)
Published: Thu Oct 08 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.