Juce Tutorial 11- Basic Wavetable Synthesis in Juce

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 actually calculate out a wave table and use that wave table to develop a sign tone okay so this is going to be a little bit different from what you might see on the juice tutorial website where they do a sine wave synthesizer the reason is that because in the juice the juice tutorial the way that they calculate out the sine wave function is they do it by by basically calculating out the whole sine wave by the frequency and they're doing this 44,000 100 times a second and there's actually a more computationally efficient way to do this and they actually say this in the tutorial so I thought why don't we just get directly to wavetable synthesis and you know use that to make our sine tone okay so that's what we're going to do today so what we need to do is we're just going to create a new project and once again we're doing an audio application I'm going to I'm going to briefly rehash over some of the things that we did last tutorial not too much but just enough so we kind of remember what we're doing here so we're going to the audio programmer we're just going to call this wave table sine okay and we're just going to create that open it up in Xcode so I'm assuming that you have some audio programming knowledge but if you don't I'm going to try to explain some of these concepts the best that I can and hopefully I'll be clearer my explanations ok so here we are we're back in the audio app component okay which has given us these three these three functions okay got prepare to play which just is kind of like our set up function just gives us our where we can declare any sort of initial variables that we need for our app okay then we got get next audio block which is our audio callback function and where we're going to do all of our audio processing then we have release resources where we can release any any resources that we need to get rid of once we close the app okay so what we're going to do first is we're just going to kind of go in here into get next audio block and create our buffer where we can where we can access the buffer and iterate through it writing values writing these numerical values still so they'll go out to the speaker okay so we'll do that using a for loop we'll call it sample okay sample is less than okay we're going to access our buffer now okay and it's a pointer so we need to use the arrow operator actually we could just do this num samples okay and plus plus sample okay so now we need to create our right positions for the buffer now in the last tutorial I think because we were doing just random numbers going into the left and right speaker we were able to just create another for loop that iterated through the left and the right channel writing random values there and we didn't get any problems now when I was practicing this when I was practicing doing this tutorial a little bit earlier I found that I was getting buzzing from what I was trying to do the sine wave the same way I was getting buzzing and I think the reason that was getting buzzing was because I wasn't treating the left and the right hand channel separately so what I need to do is I need to basically create two pointers and those are going to allow me to access the left and the right hand speaker differently now this is the best way that I've found to do it if there's somebody that's a little bit more experienced that happens to know a better way to handle this then step on forward and let us know what the better way is okay cool so we're just going to call this flip pointer Const I'm just going to call this left speaker okay and then this is going to be buffered to fill that buffer so we're just accessing the buffer now we're going to get the right pointer so we just need to access the right pointer so we can write values into it okay now the channel number is going to be zero this is going to be our left-hand speaker and the sample index is going to be buffer to fill dot start sample okay so we're just going to the first index in our buffer to prepare to write that to the left hand speaker so now we're just going to do the same thing for our right hand speaker speaker buffer to fill that buffer get a right pointer and it's channel number one and we're just going to go to the same place so what we're doing is we're just taking this buffer and we're writing it to the left and right hand speaker at the same time okay so cool so that's so that's what we got there okay so now let's ah let's go and start thinking about creating our wave table okay so as I said before what we're going to do is we're going to create one sign one cycle of the sine function okay and we're going to hold it in we're going to hold these values in an array and then what we're going to do is we're going to use another array to access what value we are within the sine function and what that's going to do is give us the value that we need to to to go out to the speakers and give us the sound that we want okay so we're going to create an array of floats okay because we're going to be holding what we're doing is we're actually holding the value of where the sine wave is at a certain place in the cycle okay we're just going to call this wave table okay now I'm going to point something out to you here that might be helpful now there's an actual array class within juice okay so this might be a little bit confusing at first but when you think array in juice it's not like standard like a standard array in C++ okay because as you probably know a standard array in c plus plus you can't arm you can't push into it you can't can't find out the size of it um so but this array when you think array in juice the array here is more like the structure is more like a vector okay so you can push into it you can access certain values delete elements off of it add elements to it so on and so forth so array in juice is like vector in C++ sort of okay so we've created an array a juicer right where we're going to hold this what we're going to hold this these values for this sine wave function okay now we need to decide how big that we want this this this array to be okay so we're just going to call this a double call it wave table size okay then we need to create a frequency for when we are actually going to put this when we're actually going to put this sine wave out to the speakers how-how-how what frequency do we want it to be okay now we need to create a phase okay the phase is just the position within that one cycle of the wave table okay that we're at so if we're at the very beginning so so think of phase as just the position like so for at index 0 then our our our phase would probably be 0 at that point okay then we've got to create an increment okay so the increment so so the way that this is going to work is we've created we've created one cycle of the sine wave then we go to the phase let's say the phase is zero we're at the very beginning okay once it's written the first value then the then the we need to know how much we need to move over before we access the next value okay and that's going to be our increment so we need to come up with a formula there that defines how much we're moving over each time we're creating each time we're accessing a new value in the wave table the right to our speakers okay so so let's go ahead and instantiate these values with and prepare to play okay so frequency we're just going to make 40 440 Hertz just middle a phase we're just going to start out at zero okay then we come to this question of increment okay how much are we going to increment by okay now what I want us to think about this rather than just kind of thrown the formula Algie we're just going to think about this for a moment okay so we have a frequency right so what we need to do is we need to define how um so so if we had if we had one cycle of the sine wave okay and the sine wave was one cycle we would say that that cycle went around once in two pi radians okay so I hope you understand this if not we may need you may need to go back to some of the audio the DSP basics that I've that I've done in some of my other courses okay so one cycle of the sine term goes completes within two pi radians okay 360 degrees so normally if we were calculating out the sime the sine function within here in c++ and we just wanted to calculate that the way just if we were just doing that just normally okay we would say that we need 2 pi then that we need the the sine wave to complete 2 pi within forty four thousand forty four thousand one hundred hertz or that's if we wanted a 1/1 hurts on toner we needed uh if we needed four hundred forty if we needed complete four hundred forty times in a second then we would multiply the frequency times two pi divided by forty four thousand one hundred hertz okay this is a little bit different in that we have a wave table size which we haven't defined yet and we need instead of instead of the wave table completing in two pi we need it to complete and whatever that wave table size we define the be okay so we're going to do wave table size okay divided by the sample rate which is for the forty four thousand one hundred Hertz okay so um we'll define our wave table size we could just start with 1,024 samples okay so that is going to be a 1,024 value long array that we're going to write the one cycle of the sine wave function into okay and we're going to do that right here and the way we're going to do that is using a for loop okay so int I equals 0 I is less than the wave table size I plus plus okay now what we need to do is we need to insert values into the array okay so we need to find our add our pushback function is if you've worked with vectors before so I believe it's insert okay so here we go so we have insert where we where we insert the value at a given position the positions going to be our index I'm just going to be I and then our our parameter type our new element is going to be the is going to be the sine function okay so let's go ahead and do that so we're going to go wave table which is the name of our array and then we're going to go I oh oh no I'm sorry wave table dot insert okay and then I which is going to be our index then this parameter type is going to be our actual sine function okay the function so we're going to calculate one cycle of this sine wave okay so I'm going to go to sign then we're going to go two times pi okay pi is written double pi a little bit confusing because double PI does not mean two pi okay which is what I thought it meant first so I thought why is it doing six point two eight whatever no double PI actually means pi cast as a double float okay so we've got double PI times I divided by the sample out no wave table size okay so do you see what I did there so we're just calculating one side function and we're putting it into the into this array and the array is the wave table size okay so this is just one one cycle of a sine wave okay so we've come we've now computed the the sine wave so now we just need to get it actually into these speakers okay so what we need to do is we need to go left speaker okay at the sample index okay so this is just the buffer equals oh is it side no no though let me think about this set so we just need so we just need the array table okay now this is a little bit tricky okay so we need to basically be use the phase okay the phase starts off at zero and then we're going to use the phase and the increment the increment is going to be how much we need the phase to move over to calculate the next value that we're reading into to push into the speaker okay now the phase is going to be a float okay but we don't we want it to be an int not a float okay so we need to cast this okay now I'll explain again why and just above it why does it give me too or a that's a bit weird well now what am I doing here so wave 2 all right I'm just getting confused okay cool okay so as I said before the phase is going to be a float okay the phase is showing us okay we're in this sign function do I need to grab my value okay now you know that an index needs to be an INT not a float so that's why I'm casting it here as an INT okay so I think that's it so I'm just going to multiply this I'm going to create a I'm going to create a variable called amplitude amplitude and I'm just going to define I'm going to go float and maybe I should make it a double amplitude okay and then I'm just going to define the amplitude as like 0.25 so it doesn't blow our ears out okay so that's just to make bestest to make this so these are going to be values going from plus 1 to minus 1 okay and I'm just multiplying that by 0.25 just to make them a little bit a little bit softer okay so we're going to go we're going to do the same thing for the right speaker wave table okay it's it's phase times the amplitude so so the thing that I'm doing with the left hand speaker I'm just copying it to the right hand speaker okay cool so if I did this now it would just probably just like click because what it would do is it would give us 1024 1024 values okay so go from 0 to 1024 but then it wouldn't it wouldn't know what to do what it needs to do after it reaches 1024 okay so we need a way for this function to wrap around when it gets to the end of the wave table okay so the way that we're going to do this is we're going to do phase equals okay so so once it's calculate once it's calculated the value that it needs at that particular index or its I don't want to say calculate calculates a bad word once it's accessed the value of the sine function of the sine function at that particular index it needs to know how far it needs to move over to access the next value of the sine of the sine wave we've calculated okay so we've got um we've got phase + increment okay okay so that's the first part of it okay so we calculate so we so we access the value that it is at a certain index and then we increment it by the formula that we've that we calculated earlier okay but now we've got a problem what happens when we get to the end of the the the end of the array okay when we need to wrap around the way that we're going to do that is using a modular function okay now since it's a float Earths yes since it since these numbers are doubles we need to use a rather than using a regular modular function we need to use F mod okay so we need to we need to go F mod which is modular for a double okay and then our first element is going to be phase and the increment and the second one is going to be a wave table size okay so what that's going to do is that's going to but if if the element gets over if the position of our index gets over our wave table size then the modulo function is going to allow us to wrap around to where we go back to the beginning of the wave again again calculate that over and then phase plus increment I think I've explained that enough already so hopefully this will work okay so I'm just going to compile now it's going to take a minute um just looking over here see if I'm missing anything I think that's everything okay as I've said before if there's if there's a way especially on this part if there's a way that you've known to do this more efficiently drop me a comment or a message and I'd love to know so stuffy ah there we go so there's our wave at 440 Hertz okay so um so I hope this was helpful and out what I'll do is shut up I'll put the I'll put the juice code I'll put this code or in the comments below just so you can check it out if you have any questions or if you feel that something needs to be explained a little bit better just um just drop me a line or leave a comment below and I hope you liked the tutorial and I will see you next time
Info
Channel: The Audio Programmer
Views: 10,627
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, wavetable, synthesis, wavetable synthesis
Id: Zz-gDMo_E8c
Channel Id: undefined
Length: 23min 19sec (1399 seconds)
Published: Tue Aug 22 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.