Juce Tutorial 23- Building a Synthesizer Pt 3 (Oscillator, Envelope, & Filter)

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 build upon the synthesizer framework that we built in the last tutorial and we're going to actually get sounds coming out of our synthesizer this time around as well as adding a component or two such as a envelope or possibly a filter so we can get some more control over our sound and start making this thing actually sound like a real synthesizer for this we're going to use the Maximilian sound library and the reason that I'm doing it this way is because I think it's easier for us to start out at a higher level and to use components that are already kind of built for us so that we can just take those and we can place them in the right places we're really concentrate on getting the code for the synthesizer itself right and then if we need to we can actually go lower level and if we wanted to build our custom oscillator or custom filter that we could do those things as a little bit more in the future but also the Maximilian sound library is an excellent library that is very useful it is a very high quality library it's been used in a number of commercial applications so that's what we're going to use today so first thing let me show you the maximilian sound library i went over this a couple of tutorials back i think two or three tutorials back so i'm not going to spend a lot of time on it but this is where you would get it and i'll put the link to it below so the first thing that we need to do is we just need to bring the library in to juice so to do that i'm just going to drag this into my header search paths and then we also need to drag it into our source window here okay and this is something that i've gone through before just in case you're wondering where i've gotten this from so check like - i think it's like two tutorials back that i did this so so we have that imported now so let's just go ahead and launch make sure that this is going okay and then what I've done is I'm included in it as a header as a header in my synth voice file here so we got Maximilian H I'm just going to build that quick this is probably going to take a second to build so while while it's building I should let you know about the discussion group that we have on telegram so I'll go ahead and link you to that group below and what we do is we have just it's just a little discussion group where we have different developers from all over the world that kind of connect share ideas we have all different experience levels some people have been doing at a very long time and some people are just starting out and so we just try to help each other out and connect and I then I hope you I hope to see you there so okay so we have so it's built successfully so we know that the maximilian sound library is successfully imported so first thing that we're gonna do is we're going to go to this this function brendor next block so just to refresh you on what's going on here so we have run the next block which we have in our synth voice class and then we're calling render next block within our where is it within our process block we have mustn't render next block okay so this is where we're gonna have our audio callback function so what we can do is we could just start in here now I looked at a couple different examples of how other people have done this and they've they've used they've used a for loop and it's in a different kind of way than what I'm used to doing it so I'm what I'm gonna do just to kind of make it easier and just kind of standardize the way that I do things here I'm just gonna do it the way that I kind of normally do it and then if anybody has any suggestions on why it's better to do it a different way I would love to hear them in the comments or just message me okay so this time we're gonna start off with the sample so so we're just gonna start with the for loop so int sample equals 0 sample is less than and then this time we're going to look at we're gonna use our argument for our function here number samples okay and then we're going to do plus plus sample so this is nothing different from what we've done in past tutorials here then we're gonna have a channel we're gonna iterate through the channels channel channel equals zero channel is less than we could just access the channel numbers by doing output buffer I get num channels I believe my audio cutter complete just never wants to work when I'm doing these tutorials is crazy okay plus plus channel okay and then we have and then we could do this we could also add this as well so we got output buffer add sample and then our our destination channel is going to be the channel that we're iterating through then the destination sample is actually start samples to the start of our sample and then we can go back to float value to add because that's going to be where we're going to actually calculate the this signal that we're going to actually put into the speakers okay and then we need so we're just gonna do plus plus start sample okay outside of that outside of that Faneuil for loop there okay so we have our audio callback here let's shall we just test out real quick I think this should work if I do a double I'll just call this the wave equals oh yeah I need to create an oscillator great okay so if we just go down into our private variable declarations here what I can do is I can do maxie ask okay so this is how we create an oscillator and then I'll call that OS c1 okay and then we should be able to say osc1 dot sine wave sorry that my my autocomplete isn't functioning right now and then what we can do is we can just go down here to our output buffer and just put the wave here but I think I think this should work okay what's what's it saying I think I think it'll be fine if I build it here okay so I so I believe what'll happen is that when i hook this synthesizer up should just be playing a sine wave I think okay okay not quite okay what have I done wrong oh this needs to be inside here okay I believe okay so let's just try this again I'll make sure my do I have to sound rather correctly sorry about this I'll put I'm just gonna put it through here sorry about this okay so now we could just go back here let's just try it again okay great cool so so so we see that we're getting sound coming out correctly through our audio callback and so that's a great start for us so now what we need to do is we need to get some control over that sound using start note and stop note so the way that we can start this out is we could start we could start by thinking okay so we have this code here where we have level equals velocity velocity is just a floating point value between zero and one this that's going to be instantiated and when I press the key on my MIDI controller that I have hooked up and then when we release the key we have this function stop note or velocity equals zero so what that means for the time being is that when I when I release the key the sound is just gonna immediately stop okay so I should be able to just say times level here okay so we have so we have this this variable level that I've set up last time level equals the velocity and then when I stop the note velocity equals zero I could just put level equals zero maybe level equals zero because I'm multiplying this by level so when I release the key should immediately stop because I'm just I'm just multiplying the sine wave times times a value either something between zero and one or if I'm multiplying it by zero it's just be zero so let's just go ahead and give that a try and then here we go we're just gonna add this connect up here okay now I'm just gonna press a note on my keyboard and as you can hear we're getting we're getting sound out and you can hear that there are clicks at the beginning and at the end so it might be useful for us to add an envelope now to control get better control over the sound okay so what we could do is we go down here we can go maxie and okay and blip one and by the way actually I guess I should show you this to you just in case you're wondering where I'm getting these functions from like Maxie asked max the end okay if you go into Maximilian and then I go into Maximilian dot H okay you can see I just happened to be on Maxie em right now okay and you can see the classes here they're actually quite straightforward to read through so then you can see the implementation in the Maximilian the Maximilian dot CPP file so if I go here to to ask so Maxie asked just to give you a demonstration of some of the capabilities here so if I go to Maxie asked here you can see that we got white noise that we can just throw in there we've got a sine wave okay and you can see that these are just wave tables okay so they're quite efficient okay just kind of standard wave table stuff okay we got cosine wave got phaser got square wave pulse wave saw waves on rectangle triangle so there's there's a lot of different options there it's really good to get started with rather than just trying to compute the wave tables yourself you know just might as well throw in the sound library and have it do it for you that's what they're there for so great okay so this is cool so we now just need to put this maxi envelope and we need to work out how we're going to how we're going to do this so what we need to do is we have this we have this function called trigger okay which is the envelope trigger because it needs to know that the envelope needs to know when it's actually going to be instantiated when it's going to be triggered okay so what I can just say here is envelope 1 dot trigger equals 1 ok so what we've got here is we've got just kind of a 0 or 1 value just to let you know whether the whether the envelope is being triggered or not ok so when we start the note we want we want the adsr or the envelope to actually trigger so that's why we're putting envelope envelope one trigger equals one here and then what we then what we need to do is we need to put envelope 1 dot trigger equals 0 when the note stop someone will release it we need to let it know that we're releasing the note ok what we're gonna do here is we're going to get rid of this level equals 0 okay there's a function in here called clear current note I'm gonna put in here ok so this is just gonna let it know that when when our velocity is 0 what we could do is we could just clear that current note out and what that allows so if we have so if we have 5 voices let's just say we had 3 voices and that we were pressing on all 3 keys at the same time and then we let one of the keys go once that once that velocity gets to zero then we want to be able to use that voice again for the next key that we're gonna press ok I hope that makes sense so what I'm gonna do is I'm gonna add this I'm gonna use this boolean from this stop no allow tail off okay what this does is it basically says whether it's going to immediately whether the velocity is gonna immediately stop or though or if we're going to allow a tail off at the end okay and this is all stuff that I've that have researched through the juice API okay so this is stuff that I've spent quite a bit of time really looking through and just experimenting trying to find the best way for these four for the code to to happen and things that work things that don't work things that nearly blew my ears out and this is where you would find all of that okay I'm instance sound actually wants synthesizer voice okay so if we just go in here quick just have a look where is it so so if we say stop note okay then you can see that there's quite a good explanation here that shows what happens with when it when it comes to the tail off and what happens okay so I'll let you go ahead and read that you know if you get a chance so so that's the reason why I'm going to say allow tail off equals true okay and then I'm going to add an if statement here I don't know if this is really the best way to do this but I thought that this would be the best way so if I say if velocity equals zero then what I could do I could just tab in here rather than him so so if the velocity is so so if we don't have any more velocity on that particular note then what we could do is we could actually just take that note and we can allocate it to the next key that we're gonna press okay and I think that's everything there okay what I'm gonna do here as well as I'm going to set some arguments for the end itself okay just so what we could do is we could start like kind of changing the sound a little bit to make sure that the envelope is actually working okay so you have some functions in here I'll I'll go ahead and I'll show you quick if we go into the Maximilian library here and then if I go to Maxie M okay this is this will hopefully be helpful to some of you if you just if you're not quite sure where to search or how they're like find out what functions are available or what sort of things are available okay then this is this is normally my go-to to go and to go in there and to just kind of search for it okay so you have a couple different ways that you can instantiate the ABS are attack decay sustain release I'm going to assume you know what that is okay I'm going to use this one double input so so we're just going to input our sound here we're going to put whether the whether the envelope is triggering or not okay and then what we can do is we look a little bit further below we have where we can set the attack decay sustain and release times okay and I believe these are in milliseconds so that's that's how this that's how they get set this might not be the best place for me to put it but I'm just gonna put it here for now just for the sake of time so if I go envelope one set attack okay yeah it's it's called set attack okay we'll put let's just put two thousand here okay so it has so it takes two seconds to actually for the sound to actually kind of come into full volume and then envelope one set decay decay always kind of confuses me I'm just going to put it at 500 milliseconds envelope one set sustain and then here I'm just going to put 0.8 this is normally the sustain is normally a value between zero and one okay and then envelope one set release and then I'm just gonna put that I'll put that in another 2,000 milliseconds so what this does is this gives us a little bit control over the sound itself and then at a later point we can actually map this two dials to our to our GUI and that we can actually control these values okay so now we just need to change we need to change our code a little bit down here so we can we can actually route the sound into the envelope okay so now what I'll do is I'll just set up double I'll set up a Verya called the sound and then what I could say is envelope one adsr I'm not gonna wait for forever for the autocomplete to come up so I'm just gonna go ahead and type in the wave and then I'm gonna put envelope 1 dot trigger okay and blip one dot trigger just once again is that one or zero value that defines whether the key is being pressed to whether it's being whether it's been released okay so now I've got I think I'll put level down here okay just so it's I don't know I just think that's the way to do it I can't really explain why at the moment and then here we're going to change this to the sound okay I don't think it actually matters whether you put level here level just affecting the wave itself so I think that's everything what am i okay I think that's fine okay so let's go ahead and give that a try now okay so succeeded that's great start hopefully this doesn't blow our ears out cuz that would be bad okay here we go we're going to test it out now great so you can hear that it takes about takes a little bit of time that it doesn't that the attack isn't right away and then when I release the key it also takes a little bit of time to actually fade off so you can see that the envelope is actually working there okay so let's just try this I haven't tried this yet so I'm not sure if this is gonna actually work and I fear that I'm gonna have to start this tutorial again but I'm going ahead I'm gonna go ahead and take a risk here and I'm gonna try a Maxie filter here so let's just try to add a filter here real quick see if that works so then what we have is I could just say double filtered sound equals filter one dot let's see if anything comes up okay so here are some of our some of our options here I'm just going to put filter I'm gonna use this these arguments here so double input so I could put the sound as the input okay we'll put four for the cutoff we could just put like maybe 200 Hertz as our cutoff residence I'll just put at 0.1 so not really much presidents and then let's just try putting this into the into our output buffer okay and let's just see what happens okay then just add our plug in here and put our outputs up [Music] actually can't tell if there's a this any difference or not oh hold on I hear a problem wherever I press the key is playing the same frequency so that's a problem ah because I have it at 440 okay that's a problem so we can just take that out and then up here we have the this variable that we set up earlier frequency and then that's that's just connected to our MIDI note number so we did that last tutorial so there we go so we could do that I'm gonna set this I'm gonna set this a little bit lower let me say a hundred Hertz maybe so we should be able to hear definitely if the sound is filtered or not okay and here we go then just add this again okay connecting I'm not sure if you can actually even hear that or not sorry about that got kind of a different setup going on here so where's my sound card one second here sorry about this people I can't can't remember where the South Ellis hearing audio output Phi so let's go into the Thunderbolt okay now we can hear it so that sounds quite musical to me so I don't know if it's filtering though sounds sounds like it is maybe maybe if I just put it really low like maybe if I put it down to like 40 Hertz or maybe it's not in Hertz maybe it's maybe it's actually a floating-point value or something I'll have to have to take a look if this isn't the if this isn't working properly okay so let's just try this mmm I don't know I don't know let's let's let's just have a look at the CPP again for low res so let's just look at low res real quick okay cut off let's see what we have for cut off hmm cut off is less than 10 cut off so I think is I'm pretty sure that it's working because because I'm not hearing as much of the sound I should probably use something with some harmonic content actually that's probably that's probably the problem so let me just let me just try that quick before we go so let's just change this and you can see how quickly like this this really kind of this this really kind of stands up you know i think that i think it's solved there we go so now that we have some harmonics we should definitely be able to hear some filtering if not i might have to just leave it for the next tutorial so here we go so let's just try this one more time okay just put this down here yeah yeah so it's definitely so so it is definitely filtering there okay so so we can just confirm that that's working so I hope that that's been helpful for you and any questions about the way that I've done that I know that I went through some of the maximilian code quite quickly like I said you know I've got some experience with Maximilian so so I've been through this documentation before a bit but any sort of questions that you might have or anything that's been unclear in terms of the way that I've done that or why I've done it the way I have feel free to leave me a comment below and ask or drop me drop me a line or join the telegram group and you can ask any of us there but for now that's where I'm going to finish off for the next tutorial what we're going to do is we're actually going to start looking at setting up some of the controls so we're gonna look in the plugin editor where we're going to be able to actually set up some knobs and dials and sliders and then use those sliders connect them to some variables here and in our filter and in our envelope and then start actually building up a GUI where we're actually able to control the parameters and make more sounds so I hope you enjoyed this tutorial and until then I will see you next time
Info
Channel: The Audio Programmer
Views: 9,602
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, synthesizer, synthesiser, synthesiser class juce, build synthesizer, program synthesizer
Id: Gsd7ESq827c
Channel Id: undefined
Length: 28min 41sec (1721 seconds)
Published: Tue Nov 07 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.