Juce Tutorial 64 - Building Your First Plug-In (2020 Update)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and in this tutorial we're going to do an update to a tutorial that I did back in 2017 where I showed people how to build their first audio plug-in so this is a very exciting tutorial that has been very popular and I wanted to do this update for 2020 because I've learned quite a bit since then and I think I'll be able to explain things a little bit more concisely than I was able to back then so let's go ahead and get started and what we'll do is we'll open up the producer so the way that I'm going to explain this is for people that may be using juice for the very first time or you may not have very much experience with C++ in general so I'm gonna go through I'm gonna try to explain everything as in-depth as possible and I hope that that's helpful for you so what she should be presented with when you open up juice is this create new project if you don't see the screen you can just go up to file and click new project and that should bring you to the screen and here we have a number of different templates that we have we can build a UI application standalone audio application the this situation we're going to build an audio plug-in so we click on that I'm just gonna put this in my development folder so this I will call this gain tutorial 20 and then I will hit create and now we have these files so if you're not sure what these files are and what they do be sure to check out my other tutorial where I explain plug-in architecture in juice okay so I'm not going to go into that too in-depth so now that we're at the screen we're going to go ahead and click this button in the center here to save and open in IDE so that's going to open us up in Xcode or a visual studio if that's what you are using okay so now we are in Xcode I'm just going to close out some of this stuff because we don't need it so the only thing that we should be concerned with is this source folder where we have our four plugin files as we said before in one many of our previous tutorials we have the plug-in processor H CPP so this does our hard math so this is where our actual digital signal processing actually gets done then you have the editor which is the user side what the user actually sees the dials and the sliders that they can actually adjust and then those will adjust some sort of number that we'll have in our plug-in processor which is more kind of our back-end so to speak so one of the first things that I'm going to do is I'm actually going to set this up so that when I launch my plug-in that it'll open up in a baw of my choice okay so this is a little bit I'm not familiar with how to do this in Visual Studio it's a little bit different but to do this in Xcode what you do is you go to the product tab and then we go to scheme and then into edit scheme and then it'll bring us to this menu here and then what we'll do is we'll go to this executable tab well click on other because we want to open a different application when we build our plug-in then I'm going to go to my Applications folder and I'm gonna click on Ableton Live that's the da W that I want to use for this but you can use any da W okay so what this means is that when this builds this will launch Ableton Live and that will be able to actually load our plug-in and if we wanted to we could actually debug it live but we won't do that in this one another thing that is very important especially if you're on Catalina I think you'll see or one of these updated versions of Xcode you'll see this debug executable make sure that you uh that or else it won't work properly so make sure that that is unchecked okay so I will go ahead and close this out and here we are okay so what we're going to build today is a game plug-in so this is kind of the hello world of audio plug-in building okay and I'm gonna do this in the most simple way possible so there are various ways that this could be better that it could be optimized so on and so forth but I'm gonna give you just a very basic foundation just to start off with okay the very easiest way that we can build this and make it work so the first thing that we want to do if we want to have a game plug-in is we would want to have a slider or a dial that controls the actual volume of the incoming audio okay so so if we go to our juice API here so I have it here in another windows so here's the website and I could put this in the description what we can do is we'll scroll down here and we actually have a class called slider so these are all the different things that you can do in juice all the different classes that you can instantiate then we have this slider class which is a convenient little class that we have for actually creating a slider or something with some sort of minimum value and maximum value and we want to control it and we can see here that if we scroll down a little bit further that we can do all kinds of different sliders we have linear horizontal linear vertical if you do rotary rotary sliders so all different types of options here okay so as I said I'm gonna take this slow and hopefully for people that are starting off this will give you an insight into a little bit more about ooh actually read the juice documentation as well so or how to read documentation in a C++ API in general okay this is something that I'm very much still learning so this is a learning process for me and this helps me reinforce things so to start off we're going to go into our plugin editor header file okay so this was the is where we're gonna declare all of our objects that we're going to create so we want to create a slider right and so we could do this I'm gonna do this in our in the private section of our class here and so I could just do this by instantiating the slider class and then I will call this gain slider okay I put an M in front of all of my member variables just to let me know that that's a member that it's a member variable you don't have to do that that's how I like to do it okay so so now we've created our gain slider and now we need to give it some sort of parameters so we can go to the CPP and here we have our constructor here so just a reminder the constructor only calls once when the plug-in is first instantiated okay so these are just kind of default settings so something like set size maybe wouldn't want to do that over and over again in our plugin okay no need to set the size every time that we're doing some sort of callback hey we only need to do that once when the plug-in is first created right so I'm gonna set a size of 200 300 here okay and then here we are in the constructor we know it's a constructor because it has the same name as the class cake game tutorial 20 audio process or editor okay so now what we can do is we can go into our slider reference here and we have all these different methods that we can call and we could set this lighter style okay so let's let's do that real quick right so we could say M gain slider which is the name of our slider and then set the slider style okay so this is a part where when I was first starting out in juice I got tripped up a lot if I still do every I still do all the time actually and so where you get to this okay we have the slider style object how do we actually call this so if you get stuck like that first thing that I do so I go back to the documentation and I go to the function call and then there's see how we have a hyperlink there to slider style I'll just open that in a new tab there and we can see that slider style is actually a part of the slider class okay so yeah just so we can see that it's an enum of the slider class okay and if you don't know when an email ms I advise you to go have a look at that very important to know for C++ okay so the way that we call this is slider style is part of the slider class and then we have these different enumerators that lets us know what type of what type of slide or dial that we want to draw so in this case we will do a linear vertical slider so the way that we do this is we go back if we can say slider colon colon okay slider style slider style is within the scope of slider and then colon colon again and then linear vertical okay so that's how we that's how we do that there okay so it's almost like an XML document so to speak so you have linear vertical is one of the slider styles within the slider class okay so I hope that that is clear for you how that works so then we so then we have a gain slider we might want to set some sort of values right so we can set a range so we've got set range okay where so here we are okay this is nice because it just tells us what it does right sets the limits of the sliders arranged okay so here we have our minimum value maximum value then here we have this optional third argument okay when we see something within parameters and it says equals something and it has sort of equals some sort of value there that means this is that this is optional okay so I could leave it out so the interval is actually how much you want to increase or decrease the slider by when the user is actually moving in the slider okay so if you don't put anything in there normally it'll go up to like five digits so you'll see something like zero point five five four three six you know and then it moves and then it's another five digit number and some people say people say all the time in the community how can i how can I make it like two digits long and this is how you do it so you could use the set range here and then we have that secret third argument so for this to start off here we could do zero point zero I put that F because I want the compiler to know that it's a float value that I want here and then our maximum will be one point zero and then what I could do is I could put in the third argument I will make this 0.01 okay which means that will anytime that I'm moving the slider it will increase and decrease by point zero one every time okay so we might want to give our slider a default value to start off with okay so in slider we can do set value okay and you may be asking how do you know how do you know what functions to call here how do you know what's available to you and the best answer that I could give to you is is experience okay is experience that's reading through the documentation okay you just have to search for these things you have to use the power of Google you have the juice forum you have the audio program or discord link is in the description you can ask there so that's the best way to find out these things okay you just got to look just got to look and see what's available to you and then what else do we have okay so if we look up here at the very top of the slider class another thing that's really nice is it shows an inheritance diagram okay so we see that slider inherits is a type of component okay component is a very is like the kind of meat and potatoes of of juice land when it comes to visual elements okay this is this is like anytime that you're making a visual element it's a type of component normally okay so what you have to do is you have this so at the moment we have this audio processor editor okay think of this is like the parent okay this is like the plug-in background that you see when you first open up a plug-in okay now any sort of visual elements that are in there are what's called a child component okay which means that it's owned quote/unquote owned by the by this processor editor okay so and what we need to do is we need to let the editor know that and we can let it know it by doing this add a make visible call here a which and then we see that it asks for the child component which is M game slider okay so so that's that's letting it know hey this game slider is a child component of the editor okay so you have so when just to knock this point home if you have a parent component that let's say it's a fully built plug-in let's say it's a synthesizer then you know you may have an oscillator section you may have like a filter section in the filter section may have like a filter cutoff filter resonance okay a couple different dials in it so in that scenario you may have the whole background that's the parent component that you may have a child component which is the filter section and then you may have children of the filter component which may be the individual dials that filter cut off the filter resonance so on and so forth okay so that's how it works is you have this parent that has children okay and you can control the size of these okay individually so so now we have the gain slider and we've made it a child component of our editor which we think of as our background okay and let's just build this really quick okay so let's let's just build it and see what we have so far while it's building just gonna let you know if you have questions or if you need further help be sure to join our community on discord the link is in the description and we have I think two and a half thousand of heading up to 3,000 developers from all over the world and all different levels asking questions helping each other out networking come join us okay everybody's welcome okay so now we're able ten you see that launched Ableton automatically and you should see your plug-in in this VST three section ok the default name is under your company and here we have it gain tutorial 20 okay and if I double click that we see that it loads a plug-in ok so that's pretty that's pretty exciting isn't it so here's our plugin so far doesn't have anything doesn't even have a slider yet okay because we haven't told the slider where we want it to be on the screen yet okay so so that's our plugin and what I can do is I can actually just load up a sample just to ensure that it's playing through the plug-in properly so if I go to loop I've just searched for a loop and we have this little bells loop I'm just gonna put this on the track here and then if I hit play we will see that the volume is going straight from the input all the way through to the output there's no change in volume nothing nothing has changed okay so no so now what I can do is I can I can actually just save this project just so I don't have to load it up every time I'll just call this gain tutorial and there we are okay so now I'll just exit out of this and now we're back here so as you saw when we opened up the plug-in it said it had something in the screen that said hello world okay that's what that's where that's that's being drawn okay I'm just gonna make this black and we could just do that using g dot fill all and then the color to use I could use the colors class and black now that will be a black background now we might want to draw our slider so the way that we could do this is using these set downs call so we got a gain slider set bounds and here we have a where we want the X and y position to be so this this refers to kind of the top left of the slider and then the width and the height of the slider so here we have let's just think about this for a moment we have the dimensions of our plugin which are 200 300 so we might want to say we want to put this slider in the middle so we might say get with it with gets the width of our plugin we can say get width divided by 2 which puts us in the middle okay then we go get height divided by 2 right then let's think about our width and height so maybe we want this to be let's just say 100 pixels wide so this is our slider and then our height let's just say 150 150 pixels on the y axis and so now we just want to make some calculations here just to put it precisely in the middle okay so so if we have a width of 100 then we will want our starting point to be get width divided by 2 minus 50 okay because that's half 50s half of 100 okay then we got get height divided by 2 - was half of 150 75 and there we go so let's go ahead and build that really quickly again let's see what we have okay so now we'll just open up our project living up this and we see that we have it but our our textbox is to the left here and so it's but it's moving the slider to the right but it is in the middle okay but I will change that shortly okay so what we could do is right here we can say don't gain slider set textbox style once again these are methods they're all they're all here okay they're all in the API set textbox style and then changes the location and properties of the textbox okay there's loads of stuff in here loads and stuff that I've never even I've never even done myself okay so once again then we got this textbox entry positioned the tens text entry box position rather hey and you say I don't know what that means all right so all you do is once again just open it up in another tab and we see that it's part of the slider class I could just call slider text box below so I'm gonna put it below the text box we have this is read-only okay we I'll make it read-only where people can read the value they can't just change it I'll set that to true let's make the width so we'll make it fifty pixels wide and we will make it 20 pixels on the y-axis okay we'll just open that up really quick and here we go okay about let's see where we are so now we are right smack in the middle of the plugin right so there we go nice little text box see how it moves point zero one in in increments and point zero one every time I move the slider so that's what that's about okay but it's not it's not gonna change anything okay seems to move this nothing's happening okay nothing's nothing's happening because I haven't connected it to the processor yet okay we haven't connected it to any sort of audio to let it know what we wanted to do it's just a slider on its own at the moment okay so that's so that's that okay so now we're going to move over to the processor side to the to the actual audio processing okay I'm gonna go down to the process block is so our process block as I've said in previous tutorials this is the most important function in our plugin this is where the actual audio gets input into the plug-in and then gets processed it goes through some sort of processing that we want to do and then it goes back out okay so I'm just gonna erase these comments here make this a little bit neater and as I've said before and I have a tutorial that's specifically on the audio process block or the audio callback I believe it's tutorial 61 or maybe 62 okay where I talk all about what this is and how it works okay so we have this vector of floats that's coming in okay so I'm just going to do this for people that are really just starting out okay try to explain this and knock this point home okay so we'll go into a little bit of basic DSP kind of theory of how digital audio actually works so here we have the loop of our audio okay and if I scroll in here really quickly we will see that we have an audio wave right so what is the audio wave so so if we think of this as a midpoint anything that's so this this is going these are floating point values that are between plus 1 and minus 1 okay so everything in here if we were to if we were just to we oh look at this we could actually see we could actually see the points right so these are points that are in between plus 1 and minus 1 their floating point numbers that are going to be actually going into our plugin so they're actually floating point a stream of floating point numbers going into our plugin I'm going to do something into those numbers and then they're gonna go back out okay so so that's what that's about now channel data it gives us a writer so so it gives us a right pointer into our buffer so this right pointer means we're gonna change something we're going to change the data somehow okay so what I can do is I can actually go use another for loop so we have this outer for loop that goes through the channels that's going we in this case we have two channels the left and the right speaker and now we're gonna go through all of the samples okay so I can do that by going int I will call this sample equals zero sample is less than our buffer and then we can get the number of samples then we'll go plus plus sample okay so this is basically going through all of the samples in our buffer and then what I could do is let's just try to make the volume softer right make it make it quieter so what we could do is we could just say channel data okay and and then so we have the so we have the channel channel 0 now we need the sample that we want to modify and then we could do I'm gonna write this the long way for people that are just starting out so let's say that we want to take each one of those samples and we just want to multiply it by zero point let's just say zero point one right so we'll make it one-tenth of what the actual original audio is it is so if it's so so what we'll do is we will compile this again and let's just see what happens right so if we multiplied it by 0.5 everything with everything that's coming in would be half the volume right so you have incoming a floating point value of one and it gets multiplied by 0.5 then it would be 0.5 okay because half of 1 is 0.5 right so now let's see what happens okay so I've so I'm taking all of these floating point all of these floating point values in here and I'm multiplying them instead by 0.1 let's see what happens okay see what happens there so we have the incoming audio see how loud it is and see how it's quieter when it's coming out okay so that's because we're taking all those incoming values and we're multiplying them by 0.1 okay we're making them smaller okay so this is a good start for us making the gain slider okay so because because now we have this and we're saying okay but we have a slider I mean what the slider to control this number right so how do we do that okay so one way that we could do this is by making a variable okay so I'll make a variable I'm gonna put it in my public I'm gonna put it in the public section of my class because I need I'm gonna need my editor to be able to access it later okay because I need because I need to tell this variable I'm gonna create hey you need to change when the slider changes right so I could say float let's just call this and gain I'll just set this to an initial value of let's just say 0.5 and now what I'll do is I'll go back into my processor and I will change this to M gain and what's M gain at the moment and gain is 0.5 okay so so now everything would be all the incoming audio would be multiplied by 0.5 okay so that's cool and that that will work fine but now we need to control the value of M gained it so now we need to control that with the slider how do we do that so if we go into our editor okay editor dot H we will see and this is another common question from that I used to have when I was first starting out and for many people and they're first starting out how do I access stuff in the processor well luckily in the template they actually created a reference to the process Hey of reference is we know it's a reference because it has this this ampersand afterwards okay so just very quickly for people that are just starting off when we have this slider AB gain slider okay there's no reference there's no ampersand after that and what that means is that we're creating a new object okay so this didn't exist before but now we are calling it into existence okay when we're talking about a reference okay a reference means that it already exists okay so we don't need to create another plug-in processor okay we don't need to create another one of these we've already got one right so what we what we're doing is we're referring to the processor which is which is essentially the memory location okay so we have this memory location and it has all this information and now we need to somehow get this M gained and we need to we need to get access to this variable okay so in pseudocode we might need something like processor dot m game equals M game slider get the value right that's exactly what it is okay so how do we do this well there are a couple there are two there are two ways we can do this I'm going to show you the easier way okay the first the easiest way is to use a listener okay listener essentially is where we tell our editor the editor is our parent component then we say we want you to listen for any changes in this slider and then when when there are changes in the slider we want you to do something okay we want something to happen okay that's that's what we are going to do here so if I go back into my documentation so I can close these out now then we got slider listener okay so here's our slider listen or class okay so so what we need to do is we need to inherit the functionality of this slider listener okay so we are just going to do this okay what that means is that our editor is so we're editing the functionality of slider listener okay so our editor is a slider listener so now if we go back to our documentation what we will see is that we have this what's called a pure virtual function okay we know it's pure virtual because it has this equals zero next next to it so when it's inside the parameter that means that it's setting that it's kind of an optional argument we're setting whatever that value is to zero when it's outside like this that means it's pure virtual what that means is that we need to and we need to have an implementation of this in our class if we're going to if we're going to use slider listener okay so so what we do is we have to create that function and we say void so so like before I do that let me just let me just build it for you and I'll show you what I mean because it won't actually build okay so and we have an error right and here it is okay um unimplemented pure virtual function method slider value changed okay so that means that we actually have to call this okay so so we go void slide our value changed okay and it takes is a pointer to a slider and then what we what we want to do here is we want to use what's called the override keyword override just means that we have we're inheriting this we're calling this function that is a pure virtual function and that we're adding our own functionality to it okay so that's what this override keyword is about okay I think it will build without that override keyword but but you want it there so people so when people are looking through your class they see that you've called this function and then you have the override keyword there and they say oh that means that this is an over written function that's part of one of these classes slider listener in this case so now we just need to implement this okay so here we go we've got void and then we need to call our class which is this and then slide our value changed okay and now we just need to connect this is where we connect our to our value of our game slider to the MD eight value that we created in our processor okay because what we want to do is we want to the the the editors of the the background so to speak is listening for when the user makes changes and when the music when the user makes a change in the slider we want to we want to go to the processor and say hey a change has happened the users have changed this value so I need you to change and gain now okay so we can do that pretty simply here if we say if slider okay so keep in mind this is a pointer here okay which means that it's pointing to a memory location okay so if we say if the slider that's changed is M gain slider and we put the amber Sam beforehand the enma-sama beforehand means a memory address okay and that's because we have a pointer here okay so a pointer what's a pointer point to it points to a memory address okay and that's why we have to put that's why we have to put this ampersand before our hand okay so if the slider that's changed is equal to the game slider okay then we want so we have the reference to our processor right so we have our processor here so the reference once just to knock this home when I'm talking about a reference I'm talking about specifically this plug in processor right here okay not talking about some sort of new processor I'm talking about that specific one okay that we've that's already been created okay so now we have this and we could say processor which is the reference to our processor and I could just say M gain is equal to M gain slider which is the slider that we created get value okay returns the sliders current value okay so we see it right there okay now there's one more thing a critical step that drives me crazy when I can't when I when I forget it and I can't figure out what's going on which is that we need to add we need we need to add the the editor as a listener to the slider okay so the way that we do this is M gain slider add listener okay add listener means okay we want we want something to listen for changes in this gain slider and then we wanted to do something what what's listening for her changes in the slider okay in this situation is the audio processor editor the class that we're in right now okay this very class and that's why I can use the keyword which is this okay we see that this is a pointer to our audio processor editor I think a lot of people get confused with what this actually is okay that's what it is it's talking about this class okay so now we are are pretty much set up okay I think we're pretty much set up we've set the gain to be modified by whatever our slider is we go into our process block we have channel data being multiplied by our gain value okay so now let's go ahead and build so now we have build succeeded the vaneeta ableton that will load up my project okay and then here we are okay we see that our slide or modifies modifies the value okay so congratulations you've built your first plugin okay this is this is an exciting this is an exciting moment okay you've built something that you can actually load up into Ableton that you can actually use to change to change sound okay that to me is very exciting okay so so this is cool okay so this is really good it works okay now we're going to make one slight improvement on this and that what we have if we look at the sliders okay these are sliders to okay they're change in volume they're doing the exact same thing okay the only difference is we if we look at the readings here we see that it's minus 60 and it goes to the top which is zero so if you've ever produced music before you know that this is in DB FS okay not not going from zero to one okay the reasons for this K could be pretty complicated and confusing to explain but to keep it short and sweet the best way I can explain it is that we here we as humans here volume logarithmically okay and what this does is dbfs actually kind of maps out the the scale of volume to how humans actually hear volume okay which is maybe confusing but I wouldn't encourage you to go check it out if you don't know what I mean by that okay so because I'll just it'll just get wordy and confusing if I try to explain it right now so what we're gonna do is we're gonna change this from raw gain value to dbfs okay which is gonna go from minus 60 to zero okay so I'll just close this out okay so let's go back into our editor so now we're just changing the range of the slider itself okay so this is very important to get right okay because if you don't then this can produce unsettling sounds okay so make sure that this is like minus 60 rather than 60 okay or else it'll it'll uh it won't sound right okay so then our minimum is minus 60 our maximum is 0 and then maybe let's put this at minus 20 okay so so that's fine and then we could go to our processor and then here so at the moment we have something that's going between minus 60 and 0 now if we multiply that by our channel data by our samples we're not going to get much of anything okay minus minus 60 or if you have like of a floating-point value a sample incoming of 1 you multiply it by 0 that's going to be 0 it's not very useful okay so what we could do is there's there's actually a handy little class called decibel the decibels class so go to decibels search that out these are nice little helper functions here in juice which makes it really nice so we don't have to do these calculations ourselves okay we could if we wanted to but why do it when we have something here to help us okay so we see that as a static function okay what a static function means is that we don't want to try to create an object of decibel type okay we don't need to go decibels decibels okay it is we just want to call this function on its own okay so how do we do that so we and in this case we have decibels okay which is what were the scale that we're talking about when in the from our slider okay going between minus 60 and zero we want to change that to gain okay so the gain is going to be between zero and one and so what I could do is when we're calling a static function we just call the class and then we call decibels just the function here decibels the gain and then in here we just put the decibels okay so the decibels in this case is our gain okay and then this will convert those decibels to our gain so let's go ahead and build that and see where we're at okay so we're building let's let's call this case and now we're at minus 20 let's see now we have something I know that you probably can't tell much of a difference but this is a little bit that are it's a little bit more useful useful and intuitive for our gain slider okay so so there we are we have our first audio plug-in and I hope that I hope that you enjoyed that so that's where I'm going to end this tutorial once again if you have any questions or you get stuck leave a comment below or join our audio programmer community on discord with the link in the description be sure to give it a thumbs up if you enjoyed this tutorial and I will see you next time
Info
Channel: The Audio Programmer
Views: 34,735
Rating: undefined out of 5
Keywords: Juce Framework, framework, juce audio, creative programming, audio coding, vst development, vst, software development, c++, audio programming, juce, plugin development, creative coding, digital signal processing, dsp, plugins, ableton, max msp, sample rate, bit depth, nyquist theorem, juce framework, tutorial, beginner, easy, games development, games programming, basics, openFrameworks, open Frameworks, ofx, Maxim, Maximilian
Id: Bw_OkHNpj1M
Channel Id: undefined
Length: 46min 30sec (2790 seconds)
Published: Mon Feb 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.