Juce Tutorial 48- Building a Synthesizer Part 8 (Juce ADSR)

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 today what we're going to do is we're going to get back into the juice synth framework here and do another tutorial this time what we're going to do is we're going to implement the juice abs our class so if I just jump into this really quick juice classes then if we go to adsr so we have this adsr which is an envelope class which allows us to control when the sound on the synthesizer is starting or stopping so if you're not sure what an adsr is check out the tutorial or discussion that I did with Aaron Lise a little while back talking about the synthesizer basics and so what we're going to do is at the moment we have a an envelope that we've implemented using the Maximilian class and as some of you have may know this is a continual issue that we've had with Maximilian for some time now where the envelope isn't working quite the way it should so juice have been nice enough to create an adsr class and that just came out in the latest release of juice and what we're going to do is we're going to replace the Maximilian envelope with the juice adsr envelope so so that's what we're gonna do so before we get started I'd like to give a couple shout outs here so first of all I'd like to give a big shout out to Shane done so Shane is one of the core developers for audio kit which is another framework that is really great so you should check it out if you don't know about audio kit but Shane was nice enough to do a pull request on the juice on the juice synth that we've done the tutorials on and what he's done is he's actually added some he's added a second oscillator he's added pitch Bend actually all that all the changes he's done is right here so he's done a whole bunch of really cool stuff and so thank you so much for your hard work Shane I know that that's gonna be really helpful for a lot of people including myself so big shout out to Shane and then wanted to give a big shout-out to a gal Amir who is a developer at waves who who actually helped me figure out the very last part to this to this tutorial I'm about to give and there was a part that I was getting this weird crash and it had me it had me banging my head on the table for like about five hours and he finally helped me just kind of get my head around what the problem was and I'll show you a little bit more about that later so what we're gonna do I've already I've already cloned the latest the latest update from Shane so what we're gonna do is we're just gonna go here into the producer and I'm just gonna hit this reload here and first thing I'm going to do I want to build for VST three here so what I can do is I can just go to the settings here and the juice in my producer and I'm going to plug in formats and as you can see VST three is is not one of my build targets so I'm just gonna go ahead and check that in because that's what I want to build for so I'm by the way you need the latest version of juice in order to be able to follow along with this tutorial so make sure you've got that so we're just gonna open this up in the IDE so as you can see I'm in this new kind of studio it's a little bit dark so if the camera is a little bit dark that's because I don't have lights in here yet so it's a it's a brand new space and it's really cool is this a little cabin that's in the in our backyard and yeah I hope my voice isn't too reverb II I can hear I can hear it through the microphone but yeah so this is a new space and it's a little bit of a work in progress but hopefully I just close out my windows but hopefully I'll be able to get some some cool pictures up in the next couple days so we're just gonna go to our API here it's just that we have all these functions and I can explain and you can walk along with me on this journey okay so here we are we're in these sense and if you're not sure about any of these parts of why why this is set up in this way then you can go back and watch the past tutorials on the juice sense synthesizer and that'll bring you up to date so looking back on this I probably would have designed it a bit differently but here we are and it's yeah and this it's serviceable so we're we're okay so what are we gonna do today so we have this we have this class that's called sense voice so since voice really defines one voice of the synthesizer so if you if you picture your pay playing a synthesizer and you're playing three notes at a time it would be three copies of this juice synth voice class okay that would be happening so just to walk you part of me super super super quickly through this so what we have is we have some pitch bending capability here and we have just just changing the MIDI note to 2 Hertz we've got the oscillator types that we got like ass all square sine wave and then we got this terribly named function called set OSC type so this is actually the audio signal so as we can see it returns a type a double so this is our actual audio signal that's determining whether that audio signal is a sine wave assault wave square wave so on so forth we have two oscillators then we have our envelope so this is something that we're going to modify with our new adsr class and then I'm just gonna skip so we've got start note and stop note when the note begins when the note ends then we got part of me then we got render next block which is almost like our audio block for our synth voice okay so what first thing that we're gonna do is we are going to actually go back to the API here so we're just gonna read through this together because I like to go a little bit slower for people that maybe beginners like myself and and so we're just gonna read through this and go through this step-by-step together okay so first thing we got the definition here where it says it's a simple adsr envelope class says the user call set sample rate and give it some parameters then call set parameters or and get next sample and so we have so we have a little definition there which is really nice to read through so so what I like to do is I like to actually go through this so some of these are very kind of step-by-step and it could be very easy to overlook these so first thing that that we do is we want to create an adsr object right so first thing I'm going to do is I'm just gonna comment out or I'll just delete this maxie end and one because that's our the envelope that we had before and I'm just gonna go down here I'm gonna say adsr adsr okay and that's our ABS our object now in here well we'll just go through this step by step right so first thing that we'll do is we need to use set sample rate right I don't know what my throat gets I'll scratch you want to start these videos so we need to call set sample rate so if we go here we see that we have a function called set sample rate double sample rate so this is something that trips up a lot of developers they think so if you look through this if you look through this class there's a lot of red by the way because I've deleted that of the loop so don't worry about that for now if you look through this class you can see that if we look for a place where we can get the the sample rate there's no place where there was a sample rate right so how do we get the sample rate into some function called set sample rate so what we can do is we can actually just do this right we can just go here and we could just create a function and we'll call this call we'll just call it void set adsr sample rate and then we could just make so if we go back to our processor so I'm just going to go over here to my other tab here and if I go to processor we can look and we can see that we have our prepare to play function here where we have this variable called sample rate and then in here I have a global variable called last sample rate and I just set that equal to the sample rate so that so last sample rate enables me to essentially pass this around to all of the functions within this cpp because if I just used sample rate it only kind of the scope of that of that variable is only in this function right so I need something where I could use it outside of this of this of this scope okay so that's why I've created this other variable called last sample ring and I can just pass that around anywhere in here so going back to our sense voice so we can see that sample rate is a type double so I can just say 80s our sample rate and I could do double sample rate and then in here I'll just say a DSR which is the name of our object or a DSR object and then I can do set a sample rate and then I'll just put that in there right and so so that's how that's how we pass that into our ABS our object okay so so that's good to go for now so it says give it some parameters with set parameters okay so let's walk through this together so we have a function here called set parameters and then we have this this type called parameters now what's parameters so let's just look into this so here we have this other type called a DSR parameters struct okay and I'll show you this in code I'm just walking through this just to show people that just kind of how this how this is built okay because this will help you get a better understanding of what you need to do in scenarios like this so I've just command click just to go into the adsr class itself here so this is the juice adsr class so we see that we have a class called a DSR and then in here we have this struct struct is essentially the same as a class more or less okay so the question it could be well how do I call how do i how do I access attack in parameters in a DSR right so one way we can do this we can think of this as a hierarchy right so we have a class called a DSR and inside that we have another class essentially or a struct called parameters so what I could do is I could say okay I want to go into the adsr class and then I use this I think it's called scope resolution operator and then we want to go into the parameters in the adsr class and I'll just call this a DSR programs okay see how I did that so that's within the adsr class and then within within that class is a struct called parameters and that's how I access that okay so now it says if we go back to our API so it says give it some parameters with set parameters right so we need to set the parameters first in here so now we got a DSR as you saw in the struct we got a DSR we got parameters and now we need to go into attack all right and we need to be able to set that now that returns a float so that means that if I want to change that I have give it another float right so what I could do is I could go up here to my get envelope params so this is where my my numbers are coming in from my from my sliders that are telling me what the attack time decay times sustained time and release time are and now I can I can just sense their float so their float pointers which means that we need to dereference what the value of attack is okay so attack is attack is a float pointer okay not just a float so the way we can do that is we have a DSR params dot attack right because that's that's just in that's just a variable within ATS our parameters and then that equals now since it's a float since this is a float pointer what we need to do is we need to access what value is at the memory that what what is the value within that memory space and we can use that doing the star operator there and I could just say attack okay so that's how we find out what the value of of attack is at that float pointer location okay so don't just ignore the errors it's just X could be in funny again so so we're just going to do this for all of these so we're just the reference e what the value is at these memory locations okay so we've got a sustain and we're setting it equal to whatever the value of our slider is that we're getting in to this function release equals release okay so so there we go so now we're setting the parameters in here just ignore these equal to whatever value that we're getting from the slider so now I can just I'm just gonna comment this out for now I think I could just get rid of this actually so I'll get rid of this just to keep our workspace nice and clean okay and then we can get rid of this because this is no longer existing and we can get rid of this okay so now what we need to do is we have a so now we need to go back to the adsr give it some parameters with set parameter set parameters right so we got set parameters and we need to pass in our parameters here okay so we can just do that in our process block because we're gonna want to get because if the person so you have this render next block that's getting called in the process or audio block and that's getting called that's getting called constantly right at audio rate so what we need to do is if the user changes the dial quickly then what we need to do is we need to we need to keep track of any sort of changes that are happening in the UI and so what we could do is we could call that here I'm not sure if it would be better to call it here or to call it in every render next block call I'm just gonna do that I'm gonna do it outside this for loop because we don't need to do it every single sample doing so I can just say abs are the set parameters and then we just need to pass in our adsr parameters object okay so we call this a DSR programs like so so now we're getting an error here because we have this function called set envelope that doesn't exist anymore so we can get rid of that so now what do we need to do so now we need to go back up and we need to find our audio signal okay which is this function here called set us type once again badly named because I did this about a year ago so we can now do set ask type which is our audio signal and then I don't know what saying that but look this is supposed to be multiplied so now what we need to do is we need to actually go back to our API here and we can do so if we go here we can say we can use this function called get next sample ok returns the next sample for the adsr object so we're taking the adsr value we're multiplying it times our audio signal times the master game which is going to be like a gain slider right so so what I could do is I could do a DSR dot get what was it get next sample next sample multiply that times our our audio signal times our master gain and then the reason that we're using an X sample is because we're iterating through the sample so we're actually changing this every so we're getting this every sample ok so that's so that's that right so now what else do we have so we need to do a note on and note off ok because we need to tell the adsr when the when the note is going on and when the notes going off ok so we got these functions called start note and stop new and we could just pop them in here note on and then here we'll just do a DSR note off okay and what else do we need to do okay so we're getting some sort of weird error there a DSR dot get next sample is a function so we just need to have our little our little brackets here so I think we're okay even though this is just acting weird so I think that's fine so now what we need to do is we need to call a DSR so we need to set the sample rate before we do any of this right so this is a this is where I kind of ran into a whole bunch of problem so I thought sample rate cool so what I could do is I could say maybe so so here if we go into our processor we have the synth voice so that's where we were just that's the class that we were just in and we have a pointer so it's a synth voice pointer and it's called my voice so what we need to do is we could call my voice and then because it's a pointer we need the arrow operator and then set sample adsr sample rate right that could just say last sample rate okay now this is gonna give us an error a runtime error here but I'm gonna I'm gonna do this just to show you what what happens and why and just kind of explain to you why it needs to be differently than this okay so we've got we're just waiting for our G's host to come up there it is okay so now I've got G sense framework now watch what happens when I do this because right sample sent the sample rate that will get used for the envelope this must be called before get next sample or set parameter methods okay so interesting right so this had me racking my brain for a while and then you have this bad access which which to me means it's trying to access something that doesn't exist right that's that's what it means to me I'm not sure if that's what the technical definition there if we look into if we look in here then we have this this is our our adsr object then it's got this memory location here and I think that this is actually trying to say hey you're not you you don't even exist yet you don't have a memory location so I think that's what it's trying to say so let me explain what's happening here and why we're getting this error so if we look up here as I said before since synth voice is a copy of every voice that you're playing on the synthesizer so when you hit two keys it's playing two copies of the voice now in one of our early tutorials we did we gave this synthesizer five voices so as we can see what we've done is we've said my synth add add voice okay now if we look now if we look in here right because I want to show you precisely what's happening so it's saying that we're adding a new synth voice to add voice now what does add voice do so let's jump into there okay so now if we look here we can see it's got some sort of lock that's happening then it's setting a sample rate and then it's saying voices that now what's voices right so voices daaad if we look in here we can see that this is a type of array of synthesizer voice so in short what what I'm saying is that when I make that call in prepare to place and let me paste this again my voice set sample rate it's the reason that I'm getting the error is because it's saying we don't know because because when I was actually when I was actually doing this sometimes it would build fine and sometimes it wouldn't and I was like what is happening so so the reason that that's happening is because you have five copies of the voice and you're having five copies of that voice and it's saying I know I don't know which voice that you're talking to talking about out of the five voices that you that you've created okay so sometimes that's why sometimes it would build sometimes it would be the right vivid it would go to the right voice and then everything would be fine and then sometimes it would say you know I don't I don't know which voice that you're talking about so what we need to do is we if we go down a little bit further in our processor we have this function here so we have this little for loop where it says the for all the voices in my sense so we've got five voices says if my voice casts successfully as a synth voice set the set the attack set that the case at the sustained Dada get the wave type do all this stuff right so what I can do is I can actually pop that here because what's happening is that this is getting all of the synth voices and it's making all of these modifications to it so it's saying okay what's the attack values the what are all these values what's the sample rate and that's why this needs to go in here rather than in prepare to play so I hope that that makes it clearer for you okay there's one other thing that I need to fix okay I'm not gonna I could build and show you an error kind of kind of error a way that this could be improved but I'm just gonna show you here rather than rather than go through that so if we go into our ABS our class we can see that in the struct this says attack time in seconds okay so the problem is is that the adsr object that we had with using the Maximillian class was in milliseconds so what we need to do is we need to change our sliders and change our process of value tree to reflect seconds rather than milliseconds okay so going into the envelope class I'm looking at the tax slider so these are the values that I'm getting from a tax slider and we can see that it's set between 0.1 and 5,000 okay so if it's all the way up and we do that now it's gonna take 5,000 seconds to for our sound that actually start the it start the attack phase that's not what we want we want five seconds right so so we're gonna do that we're gonna do this with decay I'm gonna change this 0.1 okay and then I'm just gonna change this to 0.8 I guess so this is zero point zero which is fine this is 0.8 this is zero point one and once again we got five thousand and we can just change that to five by the way some of these I'm actually just going to change this to zero point one some of these you don't want them to be zero or the adsr won't work properly and it'll probably blow up on you so don't do that so so we've done that here so now we just need to make sure that that's reflected in our parameters here so our attack decay sustain release so this is getting the values that are coming from our slider and is putting them into our processor so we just need to make sure that those changes are reflected here okay so I'm just gonna go here we got the minimum value which is going to be zero point one and then I can just make this zero point eight as I did in the other part I'm just gonna make the 0.1 and then I'm gonna change this to five rather than five thousand and now now we should be good to go okay so I think we should be good to go now so now I'm gonna go here and see so we got build succeeded so that's fine and now I can do the synth it builds fine now I'm just gonna use my keyboard here just before so you just need to attach MIDI input which is our keyboard here we need to go to our output here now if we double click we can see the synthesizer itself which Shaymin has been nice enough to improve for us and low-pass filter is really low past so we could just turn this low-pass filter up a little bit and let's see laughs oh that's very loud so I'm just going to turn that down a bit that's fine because we can see that it's a square wave and oscillate so now let's try to turn up the release a little bit and we can see that that's working let's turn up our attack a bit and we can see that that's working so this actually works fine so that's that's really it that's the end of this tutorial yeah so so yeah once again be sure to make sure that you watch that set sample rate function that could be a little bit tricky took me a little while to get my head around so I hope that you liked this tutorial be sure to give it a like and subscribe and all that business if you liked the tutorial and I will see you next time
Info
Channel: The Audio Programmer
Views: 2,592
Rating: undefined out of 5
Keywords: juce, juce framework, c++, audio, tutorial, audio programming, creative programming, creative coding, dsp, digital signal processing, vst, create vst, create plugin, audio plugin, oscillator, synthesizer, maximilian, openframeworks, software development, beginner, easy, max msp, juce synth, synth envelope, adsr, adsr envelope, dsp programming
Id: bVymZ3Oau9U
Channel Id: undefined
Length: 30min 16sec (1816 seconds)
Published: Tue Mar 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.