Juce Tutorial 41- Building a Delay Plug in Pt 2 (Creating a Delayed Signal)

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 as you can see this is the first tutorial where we actually have a camera here so you can actually see my face and I'm not just some mysterious voice with a bunch of code so glad to have that going now and so what we're going to do for this tutorial is we're actually going to make a correction from a small little error that I did the last tutorial where we've been building this delay plug-in and then just building on what we did in the last tutorial so so in the last tutorial we created another buffer called a circular buffer and what we could do is we could take the audio and we could copy it from our main audio buffer over to our delay buffer now what we want to do is we want to create a delayed signal or a delayed effect and what this requires us to do is this requires us to look at a position from our delay buffer so if we have our main buffer copying to our delayed buffer then what we want to do is we want to be able to look at a piece of audio from back in time in the delayed audio buffer and then we want to take that and we want to add it to our main buffer and what it'll do is it'll create two sounds so it'll sound like you have your main kind of audio playing and then there's going to be another piece of audio that's going to be the same thing as the main audio but it's going to be a period of time behind playing a period of time behind what the main audio is playing and that's going to give this kind of delayed effect and so this is what we're going to do for this tutorial just creating the delayed effect we're not creating a UI or anything like that just creating the effect the very very basic effect itself okay so the first thing that we're going to do is we're going to just correct this error that I made last tutorials so I said that our delay buffer size so we want be basically two seconds of delay time so if were operating at a sample rate of 40 for 100 and we wanted two seconds of delay time so you have 40 for 100 44,100 samples that are playing every second and now what we wanted to do was multiply that times two and that would give us 88 thousand two hundred simples in two seconds right so I was just following from from my friend Daniel Wallace's example that he built in his in his delay plug-in and I'll link that below and what he did was he actually did it like this rather than a multiply sign here we just did a little plus so what he's done is he's actually given us two seconds of delay time plus a little bit of extra for just just by using the samples per block which would be about 512 that would give us 1020 that give us 1,024 more samples within two seconds so it's just a little bit of extra room it doesn't really make a difference I don't think so we could just leave it at two times the sample rate if we wanted to so yeah so that should be a plus sign and not a multiply sign okay so moving on so moving down to our process block just reviewing what we did last time so we've got this delay buffer that is just a copy of our buffer and then we just made it a bit longer so it's it's got two seconds of of time that we could basically put audio data into and now what we're doing is we're taking our buffer our buffer data and then we're copying it into our delay buffer and as I said before we have to do this little bit of math trickery just to make sure that when we're getting to the end of our delay buffer because the buffer the main buffer and the delay buffer are going to be of two different lengths so what we want to do is we want to make sure that when we're coming to the end of the delay buffer we're doing a little bit of trickery here just to make sure that we copy from the remaining samples to the end of the of the delay buffer and then we're wrapping around and we're going back to the very beginning of the of the delay buffer and then we're copying the rest for that particular iteration okay so if you don't know what I mean just make sure you check out my last tutorial okay so first thing that we should do is as I was saying before we could just take this and we could probably just move this out to a different zone function here so that's what I'm gonna do here so let's go ahead and just make a function will call this void fill so we need to put our class type here so our fully qualified class I believe it's called so we're creating a function we're gonna call this fill delay buffer and then I'm gonna put some I'm gonna put some arguments in here and we'll just what we'll do is we'll copy all this in first and then we'll then we'll figure out what sort of arguments we need to have within this function so I'm just going to clean this up here so what do we need we need the channel first of all so we need int so would that be constant channel so we need the buffer length how many samples we have in the buffer so we got cost int buffer length and then Const int delay buffer length okay and if you're wondering where I'm getting these from it's just right here okay so buffer length is just buffer get number samples so on and so forth okay so now we need our buffer data and our delay buffer data so we've got cause float buffer data cants float delay buffer data so now I'm just going to do this copy this back into my header file so we'll call this void fill delay buffer and do it like that I think we should be fine so I'm just going to run this quick just to make sure that I've got everything set the way that I need to so we've got a little Oh what about done there Oh copy this room so there we go let's let's try this again we should be should be fine okay so that's cool so now we just need to go back into our process block here I'm actually going to move first thing we're going to do is I'm actually going to move this out this should be outside of this iteration of going through channels because we want that just to happen once every process block not every not every time that we iterate through a channel okay so and so you can see I got some errors here these are out of scope from my for loops and now I can just take these I'm just going to move these up here so now we're within scope of the process block itself so we should be good there now I'm just going to remove this blank space here keep everything nice and formatted correctly and then I'm just going to put my function in here fill delay buffer and now we can just put in arguments so we're iterating in this for loop through the channels we got buffer length I've just kept the names the same so we so we so we can just copy these in nice and simple so we got buffer data delay buffer data and then there we go so now we need another function here so I'm just going to call this void you need our fully qualified class here and then we're going to call this get from delay buffer and then I'm going to let's talk about what we're gonna need here so we're going to need our audio buffer here so I'm going to put that here we're going to then we're just going to need a lot of these same arguments that we have for this other for this other function so we need the channel any cost it buffer length cost its delay buffer length I don't know why I just don't copy this yeah probably a bit quicker so they could just do like this and then I'm just going to do this add some brackets here like that and go down here [Music] make sure this is void okay just compile quickly just to make sure we don't have any thing that we missed okay so what I've got here is I've got the juice plug-in host already kind of lined up at the moment so just just to reiterate on that just in case you've forgotten how to do that really quickly if you go into product then scheme edit scheme and then if you go into your executable then you can point to your your build in your audio plugin host within the juice folder okay Allah what I'll do is I'll put a link right here for the video where I show you how to do that I don't want to really waste time going over stuff so okay cool so let's go through how to get this how to get this delayed signal going okay so first thing that we need is we're going to need a delay time okay so I'm going to go into delay time equals let's just say 500 milliseconds okay so this is gonna I might trip up a little bit here as I'm just kind of thinking this through because I'm trying to do this off of memorization rather than just looking at somebody else's code just so I can kind of get through the process myself so bear with me please so now so we got this Const so now we got the delay time so now what we need to do is we need to create what's called a read position so what that's going to do is we're going to have our delay buffer which is so we have our main buffer we have our delay buffer and those are writing those so you so we're copying the values from the main buffer to the delay buffer now what we want to do is if we want to fetch the if we want to fetch a piece of audio from back in time we basically need to go back in time in our delay buffer and we need to grab that audio and basically read from there forward rather than reading from wherever we're writing from because if we're just reading where we're writing from then what we'll have is will just have the same signal again okay and it'll just be twice as loud because it'll be the piece of audio just playing over over itself okay it'll be played twice so we don't want that we want to be able to move back in time to a position in our delay buffer that is previous and then be able to read from there okay so we're going to create this other variable we're gonna call this read position and so let's let's think this through okay so if I have delay time and we're talking in milliseconds we can say and we have thousand milliseconds in a second right so if I say 500 in a thousand milliseconds now we know that we're talking about a half a second delay right and now if I say that I want to do a sample rate okay we got a problem though because we don't have a global we don't have a global variable that tells us our sample rate so let's just go ahead and create one quick so we'll go back into our header file here we'll do int m sample rate and then I'll just default this to 44 or 100 and I know that if the variable is global that it defaults to zero automatically so I'm just giving it another just a safe a safe value there so we don't have a default sample rate of zero even though we're just going to change this in our prepare to play here and set it equal so what we're going to do here is we got em sample rate and we're just going to set that equal to whatever our sample rate coming in is so now we've just made that sample rate whatever whatever sample rate we got coming in here okay so we're fine now and now I could do M sample rate and okay so let's see what else what else we need to think about so we're gonna have delay buffer length plus so let's think and I'm just construct I'm just constructing this here so we need to make sure that it wraps around in the in the in the delay buffer so we're not we're not ever going off the edge of the delay buffer so at the end we need to have modulo delay buffer length okay and then let's see this 500 actually needs to be delayed time star about this okay and then so let's see delay delay buffer length plus so we need the we need to know the right position right because we need to know we we need to know because the right position is letting us know when we're copying from our main buffer to our delay buffer then the right position is going to the place where where our pointer is at right so where we've or we've actually written to so we've written all the data to here and now we need to go now we need to see where we are in our buffer and be able to go back from there right so we got to go right so here we got to go right position so right position and then we're going back in time all right and then what have I done there so oh so I need a semicolon there okay so what we need to do now is we just need to make sure that this is actually going to is it going to always end up and then being an INT so I just want to make sure that this is always going to be an int so so what I'm gonna do just to make sure is I'm actually gonna use a static cast into an INT okay so this is this is effectively the same thing as if I if I did this okay so let's let's just take this out for a second and if I did if I did this right but this is the old-school way the C C style way I think they say so what we want to do is we want to now use static casting okay we're going to cast that into an int okay so that is effectively the same thing as what I just did there before putting the int in parentheses and doing a cast there so this just makes sure that whatever whatever we have here the result of that is cast to an int okay so now that we have that now we need to start thinking about our how we're actually going to get this from we're going to add this from the delay from the delay buffer back into our regular buffer so if we say if delay buffer length is greater then so what we're doing is we would normally be copying our buffer our buffer plus which is I say plus which is actually going to be a minus because we're actually going back in time okay ah plus the read position okay so what we're saying is we're going to look at where we're going to look at the delay buffer length and we're going to say okay is there enough space in the delay buffer wherever we are in the delay buffer where we can actually take the the 5 let's just say the buffer length is 512 values or we could take 512 values plus whatever our reposition is so we probably go back into the past here we just want to make sure that we're not going off the edge of our delay buffer and so that's why we're doing that so we're going to do buffer ad from okay so we're what we're doing is we're adding something to the buffer from the delay buffer okay so let's see I think this is the one that I want so in here we're iterating through the channels so I can just put channel here destination start sample let's think about this so we want to start from zero I'm just going to put zero for now I think I think that's what I want and then here I want to have the delay here I want to have the source which is going to be delay buffer data plus a reposition right because we need to know we need to know where we're we're actually reading from mmm and then this is going to be buffer our buffer our buffer length because this is how much data that we're actually copying we're gonna copy our buffer length okay I think that that is right okay mmm delay delay buffer data okay so I think that that is right okay I might have to go back and check that so what this means is that if we aren't near the edge of our delay buffer like when I say near the edge I mean coming to the end of our delay buffer picture it is a vector that's holding values of floating-point numbers what we're going to do is we're just going to take it and we're going we're going to take from the delay buffer we're going to go back to our read position and then we gonna copy from that reposition back to our main buffer okay but now we need to put in a condition that defines what happens if we get if we get near the edge and there aren't enough values to copy from the delay buffer back to the main buffer so what I mean is if we're coming to the end of the delay buffer and let's say that let's say that we have 10 values that were our buffer length is 10 values and we only have 5 values left then what we need to do is we need to we need to take the 5 values at the end and then we need to go back to the beginning and we need to take the 5 values from the very beginning ok of the of the delay buffer ok so we need an else and so we need to do a we need to find out how much space we actually have left in our buffer right so we could do buffer remaining equals delay buffer length minus a read position okay so that will tell us how many values that we actually have left in our in our delay buffer that we can actually copy right so now I'm going to do another buffer add from and then so so we have a buffer there it's going to be starting at a value 0 again right and then here we're going to once again need our delay buffer plus our reposition because that's gonna let us know where we need to be in our delay buffer to start reading the data from and then here we need buffer remaining so that lets us know how many spaces we have how much how many values we have left in the delay buffer that we can copy from right then we need to go we need to do one more because so so what we've done is we've like once again let's say your are let's say our main buff that that our delay buffer has five values at the end and five and then our buffer length our main buffer length is ten right so now it's copied five values at the end put it into our main buffer but now we have five more values that we need to do before we actually fill the rest of our main buffer so we're gonna do buffer add from again and what happened here so buffer dot add from why is it why is it not giving me buffer add okay that was weird okay so let's do so here we need to go from our buffer so so we're gonna have buffer remaining amount of data that we still that that so we need to go to the yeah so we so we have buffer remaining amount of samples that we've that we've copied to our main buffer so now when we go in so now we're going to copy from our buffer remaining position because that's how many values we've just copied into the main buffer so now we have now we have buffer remaining amount of samples in our main buffer and now we just need to do the rest so now we could do just to lay buffer data by itself and then this should be the buffer so so we need the buffer length how many the total length of our buffer - the data that we've already filled which is buffer remaining okay so that should be alright I don't think that I've I think I've got all that right so get from delay buffer so let's just try that and then we're going to fill in our arguments so we just have our main buffer we have the channel that we're iterating through we have buffer lathe then we have delay buffer length we have buffer data delay buffer data I deserve a beer if I get this right the first time not that a drink I don't really drink but okay cool so now we're iterating through the channels we're filling the delay buffer we're going to get our data from the delay buffer and we should be fine okay so I'm going to just build that now and let's test it and hopefully I haven't messed anything up okay so I've got an audio file in here already let's see what our delay time is so our delay time is half a second let's just see what happens hey it works I can't believe it so let's just just to make sure that it actually works let's just try a really short amount of time let's just try 50 as our delay time okay so we don't have a number dial or anything that can control this delay time yet so we're just gonna have to try different different ones let's just see here so hey how about that it actually works I can't believe it I can't believe I got that right the first time so once again big big up to Daniel walls who's a good friend of mine and he's really taught me a lot he's taught a lot of us a lot of knowledge if we've ever been on the Jews forum or in the discord chat platform he's just always in there answering questions and he's just he's just a demigod of C++ development at least to me is so big up to him because this is something that I've picked up from him looking at his delay plug in and I'll link you to it be sure to follow him and support him because he's just a really cool guy and if you like this video be sure to give it a like and to subscribe to the discord channel and come chat with us we have a whole bunch of great developers and our discord chat platform and if you feel like give it a little bit money go ahead and give up you can donate via patreon you don't have to but but it's always nice to see your support and I hope you enjoyed this tutorial and we'll see you next time
Info
Channel: The Audio Programmer
Views: 4,755
Rating: undefined out of 5
Keywords: delay vst, delay effect, delay dsp, 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 delay tutorial
Id: TXUvRJWBY7E
Channel Id: undefined
Length: 30min 25sec (1825 seconds)
Published: Mon Aug 27 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.