Juce Tutorial 37- Building a Simple Audio Player

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 in this tutorial what we're gonna do is we're going to finish building our audio player that we started building our last tutorial so just to review what we did our last tutorial we actually just created the functionality where we can actually just hit an open button and then our regular window opens where we're able to select an audio file and choose it and it'll load into an audio reader and we're going to be able to read from that source using a transport so what we're going to do this tutorial is we're going to actually create our play and stop buttons that we're going to actually be able to play our or our track and then stop it and of course with our over button we can choose a different track if we want okay so it sounds like a really simple thing it's a little bit more it involves a couple more things then I think most people would think so we're gonna go ahead and get started and if you find this video useful be sure to like and if you're not subscribed subscribe you know means a lot to me and what I'm gonna do with this tutorial is I'm going to as usual kind of go through my own thought process of you know how I like to think through actually implementing these things so I don't have any notes with me or anything I like to kind of test myself just to like think through the process and this is based off of the juice tutorial on building a simple audio player so be sure to check it out so we're gonna go ahead and get started so we're good once again we're going to implement some play a play button and a stop button that's going to be able to play or track and stop it and then of course we already have the open button where we can reload load another track if we want to okay so first thing that we're going to do is we're going to actually create these buttons so I'm going to create two new text buttons so this one's gonna be called play button and we're gonna do a stop button and then we're gonna go over here we're just gonna go ahead and initialize these with some names here so this is just in our initialization list and we're just going to call this play and then we got stop button and this is gonna be stopped and now we're just going to do some initial settings here so we need to tell the play button what we want it to do what we want to happen when the user actually hits the play button or the stop button so we're going to set that up now so we're going to use play button on click and this is something that we went through our last tutorial with a lambda function so if you're not sure where the lambda function is check out my last tutorial or there's a really great talk from cpp con on how to do lambda functions and it takes you like on a whole tour of it and maybe I'll make it oh I'll put a link to it below in the description so check that out so what we're going to do is we're going to create a function that happens when we hit our play button there and I'm just gonna leave that blank because I haven't created the the function that we want to happen when the user actually hits the play button ok so I'm gonna do the same thing for the stop button and once again we're just going to listen for this event listening for when the user actually hits the stop button and then we're going to define what the what's gonna happen there so it's gonna be two functions like play button click to stop button clicked so and we're gonna make those visible and we're gonna do the same thing with the stop button by the way I'm flying through these parts a little bit quicker because it's stuff that we've already kind of gone through if you feel that it's too quick just drop me a comment below to let me know I'm always curious if if what I'm saying is too too quick or too slow so just let me know don't be afraid if if if it's going too quick for you don't be afraid to say so so I can like slow it down a little bit okay so what else we're gonna do is we're gonna set this to some colors so we can do play button set color and then this is what we're actually going to do if we're gonna color the outline or if we're gonna color the text or and we're just going to color the button itself so this is a button color ID and then this is going to be the play button so we're just gonna set this to green great do the same thing for the stop button color text button button color ID colors red okay another thing that we're gonna do here is what we're gonna set the play button to enabled and then we're going to disable the stop button so you know on those web players when you when you hit the play button basically this the stop button kind of comes out at you and that's enabled now so you can hit the stop button but you can't hit on all most web players you can't hit play twice once you hit play once then is playing and that's that that option is disabled for you now and so that's what we're gonna do here so since our initial kind of state is going to be is that the player is going to be stopped we're going to enable the play button to start off with so set enabled is what we want and we're going to have true there and then stop button because it's gonna be stopped we don't need the user or want to give the user the option to press stop again because it's already stopped so we're gonna do set enabled to false for the stop button okay and I think that's good for that so let's just go ahead and draw these now so they got play button set bounds and since the height of it is 30 we can maybe set the distance between them to be 40 so we'll do 10 we'll do 50 which is 40 from 10 the open button then we got get width minus 20 and then 30 and then stop button set bounds 10 and then we got 90 get with - 20 30 okay and we're going to go up here we're going to actually just give us a look give our our component a little bit more of a height there so just reset that to 150 so let's just make sure that everything is where we want it to be so just building it here quick and that looks good so we have our play button as you can see the stop button is kind of faded out so that's disabled the user can't press that but the user can press the play button to start the track so that's all good so now what we need to do is we actually need to create functions of what we want to happen when the user presses the play button or presses the stop button okay so we'll go back to our header file and I'll just create two new functions here will do will do void play button clicked and void stop button clicked then we're just gonna implement these here so here we go I don't know why it's crossed out when I do when I go to autocomplete that curious about that but and then we got stop button clicked and there we go so so that's fine and then we can go back up here and we don't have anything implemented in there yet but we will so we got play button clicked and then the same thing down here stop button clicked cool so when the button gets clicked then these functions get called okay so so far we're so far we're fine so what we need to do now is we basically need to have things happen when we hit the play button or hit the stop button so we're going to need a couple we're going to need a new class here so that's going to play our audio files let me pull it up here for you I've already kind of pre-loaded it for you so this is called audio transport source and so this is just a positionable audio source that lets us play or stop our file so so if you think of a transport like any sort of transport in a MIDI aw like Ableton or logic when you hit the play button and it starts or stops so same kind of concept here so audio transport source okay so I'm just gonna create an object here that's gonna be called audio transport source I'm just gonna call it transport okay so that's fine and so now we have a transport and now what we need to do is we have these we have these functions here right so we can do we can start the transport to start playing the file or we can stop it we can check to see if it's playing we can set initializations of prepare to play that reminds me we can actually do that right now so we can do we can do a prepare to play implementation here so in prepare to play so just get rid of all this and we could do transport prepare to play that just takes two arguments here our buffer size so samples we're just getting that from the prepare to play function there and we're just plugging those in so we've got sample rate here and that's all good now okay so okay great so now what we need to do is we need to basically create some states some different states that we can associate with the buttons that we have so when the button gets clicked then it is in a play state when the button when the stop bug gets clicked then it's in a stop state okay and what we can do is we can use a in an enum for that enumeration okay if you if you're not sure what that is I'll put a link to that below okay so this just enables us to kind of give it some you know it's a little bit more useful for us to use an enum rather than just saying like state equals 0 you know and then 0 doesn't really have any meaning so we can actually kind of associate some words here rather than just having like just some integers that would like describe our state I hope I explained that right so so what we can do is we can start with a stopped state okay so stops will be like when when the player is initially loaded okay then we have a plane no we'll do a starting state then we'll do a stopping state okay so this is just what we're going to do is we're going to basically say if the state is started oh I forgot to give it a name actually so this is uh we're just gonna call this transport state all right and so what this enables us to do is to kind of give some names that are gonna be a little bit more useful to us when we're describing what we want to happen in different states of the application okay so first thing I need to do is create a transport state object so transport State just call it state okay then if I go over to my constructor I can give it an initial an initial state of stopped okay so I could just say state and then stopped it doesn't mean anything yet because we haven't we haven't told the application partly we haven't told the application of what we actually wanted what stopped the mean yet okay so well we'll do that shortly okay but what we can do is we can actually go down here into play and for now you know so this is just something that we're gonna do as we kind of build the application up right when the play buttons are clicked then I want the state to be playing or starting rather okay or actually it would be like this starting okay so this is just to show you kind of how I'm thinking of of this you know going through the steps here so and then when we hit the stop button then the state will be a stopping state right so so that should be pretty self-explanatory so now what we need to do is we actually need to define what those things mean okay so what we could do is we can create we can create like a function that says okay if the state is stopping then we want it to mean that the transport stops and then the play button gets enabled right so let's go ahead and create a function here and we'll call it void transport state changed okay and actually we need we need an argument in here because we need a transport state so we need to know what the transport state is then we'll just call this new state okay and then we'll just go back to our CPP and we'll implement that here I'm just gonna copy and paste this actually like so so we got void being component like that okay so a lot of this like a lot of these things that it checks is stuff that I've actually gotten from the juice tutorial and it's really well-written and you know since it's well written it's like why reinvent the wheel you know try to learn from the best people that are doing it in the business so so let's go ahead and get this started so basically what we want to do is we want to have a continual we want continually checked to see if the if the any new state that we select is the same as the state it is currently and if it's not then we need to basically make some changes right so if I say if let's see here so we have if the new state is not equal to the current state right so basically if if our state changes like if we click the stop button then the state is now stopping right then then we basically need to tell it what we wanted to do right so if the new state is not equal to the state what we could do is now we can make it the state the current state right so the state equals the new state so we're just taking the new state and we're setting it to what the current state is now okay and then what we need to do is we need to define what's going to happen when these states change so we want so basic basically what certain buttons to enable and certain buttons to disable and we want the transport to start or that we want the transport to stop okay so let's just go ahead and before we kind of go into this we can maybe pseudocode some of it outright so if we have stopping right so if the person hits the stop button then what we want to do is we want the play button to enable and we want it to stop right transport stop and then if we have plain or starting keep saying playing then we want let's see here so if we hit the play button then we want to enable the stop button and then we want the transport to play right so we want to start the transport and then we have that initial state which is stopped and then what we want to do is we'll if it's if it stopped then we'll just bring the transport back to the beginning and I think that'll be fun okay so let's just start there so what we're going to use for this is we're going to use a switch statement okay pretty pretty standard stuff in C++ and you know loads of other languages I think pretty much every language uses a switch uses the switch switch statements so what we want to do is we want to do a switch depending on the state okay and so for the first one we'll do stopped alright so we're going to just define what happens if the if it's in its initial state which is just stopped so we can say transport set position and put that at zero so it just brings the transport back to the beginning okay and we need to make sure that we have break in between each one of these or else it won't work right okay so then we'll go to case and I'm just going to keep these in the same order as here I don't know if you actually have to but I think I think it's good practice so we got starting and then we're gonna say so we what stop button enable or set enabled to be true and then we want transport start okay so that just means that the transport is gonna when we when he hits the play button the transport is going to start playing okay we're gonna probably get some little kind of bugs in here so bear with me if if it's not completely right the first time so so we got stopping and then we need to play button enable set enabled and that's true and then we need transport to stop and here if it's oh yeah so a couple more things here so if it's stopped then we want play button to be to be enabled this is that enabled true here if it's if it's starting that we want the play button to be disabled so this might take me a few times to actually kind of get this right so then if it's stopping it's that enabled to be false so if they hit the stop on we don't need them to hit the stop button again okay so I think that's okay okay so I'm just gonna clean up some of this code here great okay so now what we can do is we can go up here and we need to actually we need to actually do some things to enable our transport to be able to play our audio files so we actually have to set the transport to play that particular audio file so that's transport set source okay and the source is our temp source and then I believe it's just yet so we're just getting the data that's in this from our that the so so it's not so this is something I should actually clarify so this is a pointer so it's not temp source isn't like holding data it's just pointing to an out of audio format reader source that is holding that that is holding the data okay so it's a pointer it's not like the actual data itself okay so so we got that I'm going to get rid of this you don't need that anymore I feel like I'm missing something here oh there's something else I actually forgot to mention there was something I was I was wrong about in my last tutorial that I wanted to clarify here so if you wanted mp3 files to be enabled to to play or a selectable from mirror when you're actually looking for a file I thought that you have that you did did you do it like this mp3 like that but that's actually not correct what you do is you actually just put a semicolon there like that and then you add your additional audio formats right here like this okay so now now mp3 will be selectable okay so let's see here so we've got so this this is fine okay so what we need to do now is we actually need to attach the transport state changed to win our play button clicked and stop button clicked or actually playing and when these events were happening so now what we could do is we can just say transport we can call these functions within this play button click now and we can now say now that transport state changed ooh it's starting I keep on saying plane okay cool and then you can do the same thing here transport state changed and stopping okay so when they hit the stop button then unless it's good let's just go through this for a second make sure that this is right I feel like I'm missing something so when the user hits the play button that's that's starting that's in a starting state the stop button gets enabled the play button gets disabled okay that sounds right to me and the transport starts okay when the stop button is clicked the play button gets enabled right because we want the user be able to start it again if they wish the stop button gets disabled and the transport stops okay oh I forgot to put brakes here maybe that's what I felt like I was missing very important to have those there won't work right okay so let's just let's just give this a test run and see I don't I don't know if it's gonna work quite right when this first time around but you know let's see so here we are we got our player let's go ahead and open it and so we have a wave file we have an mp3 file here so we can so we can load up either one of these let's load the mp3 let's see if this actually plays okay so it doesn't doesn't actually play and it doesn't look like it stops properly either okay cool so we just need to go in here and see what we need to do here so this might take me a second oh yes of course I didn't put it in my getnext audio blog I saw something else was happening there but let's just take care of one problem at a time so we could do transport dot get next audio block okay so this is just how we actually get it to play out these speakers okay we just put that to our buffer and now let's now let's try mmm okay so compiles okay and here we go let's load an audio file let's play great okay so let me just load an mp3 save that place great okay that works okay so now there was one thing that I wanted to try so let's play this okay so this is one thing that we just need to quit quickly fix and I think I know how to do this I think it was something I've seen so you saw it was playing I saw I had so a file was playing I hit open to load another file now when when I hit when I opened another file it stopped but you noticed that I'm in a situation here where the stop button is now enabled now I have to hit stop and then I have to hit play okay whereas I just want to hit play so what we need to do is we need to actually create one more state here okay and we'll just call that playing okay so we'll just go over here we'll add another state to our Eve numb so we got playing and then where did I put that in my so I put that second so I don't know if it's important to keep these in order but I think it's probably good to good practice so we got playing and then what we need to do is we need to do play button enable set enabled to true okay and then break and then let's see let me see here so when let's see so I think that there was a place that I needed to put this okay so first thing I'm gonna do is I'm gonna go in here and I'm going to okay I'm just going to do a few things in here so once the read once the user chooses a file here then we could do if reader it's not equal to null pointer then we want the user to be able to do all this stuff okay so that's that's so if the reader if the user chooses another file now we have all this stuff that's gonna happen here so I'm going to do a transport state changed here to stop again so that brings it back to the beginning and stops stops the file stops what once the user hits another selects another file then it'll stop it and bring the next file back to the beginning okay so and then okay so what we can do one more thing that we can do here is we can actually add a listener to listen for changes in the state so let's go ahead and do this quickly so if we go over here we have the change listener class so this just listens for if if there's any event callbacks that are that are that are changed okay so we just need to implement this in order for us to be able to see when when our file has changed so that so that we can actually reset the state okay I hope I'm explaining that right so we need to inherit here so we need to do change listener so we're gonna inherit this functionality change listener I was getting nervous when it doesn't autocomplete okay so now what we can do is we can go in here and we can do transport add listener as add listener her changed state when the state changes and then we can just have it listen for any state changes mmm okay what's going on here transport state changed okay I'm just gonna add a listener it's add listener transport add change add change listener that's it okay here we go so let's go with this and I believe there's a virtual function we have to implement here so we have to just say what happens with a change listener call back here so that's a virtual function so what that means that we have to implement it when we're inheriting from change listener okay so we can go back here and we just need to do this void what's it called change listener call back just going to just copy that just for times sake okay and then I'm just going to copy that oh this is this is gonna be override as well so because it's inheriting because it's a pure virtual function we have to well we don't have to but we should put it override market as override so that anybody that's reading the code knows that that's a virtual function and not just some function that we just created out of thin air okay so let's go ahead and implement this here and I'm just gonna do void main component okay so we need to define what happens if there's changes in the listener so if source oh man I'm losing it here I'm losing I'm losing my train of thought what is it that I'm looking for if sorry about this I'm just gonna consult some notes here really quick just so I don't have to I don't have to restart this tutorial sorry about this I do forget every now and then so oh yeah oh yeah that's it that's it that's it so so basically it's listening to see if our source is the is the transport that we have so if we have if source is equal to our transport we need to use a reference here and then we need to check to see if the source is playing if transit if the transport is playing then we just make sure that the state is set to playing so transport and I feel like I'm losing it here transport state changed playing okay and then else transport state we just put it we just set it to stopped okay that should do it I hope it's a bit of a bumpy ride there so my understanding on that on that part is a little bit hazy on that but I just had to consult the juice tutorial on that last part so it's just actually listening for changes and if and just if the if there's a change then it sets it to stopped again so let's just see if that works or not so we're gonna play okay okay cool so that works that works fine except I saw that the that the stop button didn't disable when it went back to when it when it reset again so we need to do stop button set enabled false okay so now I'm just gonna try this again and we should be fine now okay so we're going to open the file play it then open okay great then it it didn't set it when let's see so when it's actually playing stop on set enabled true oh yeah I'd have to go back here and debug debug some of this but okay so let me let me just try one more thing yeah I might just leave you here it's a little bit it's a little bit buggy but it actually it does actually work just it will just take me a second to actually work through all these through all your right but I mean it's pretty much all this there so I hope you can forgive me for not having it a thousand percent completely yeah yeah it'd take me a second to go through this and just actually debug it but but it's mostly it's like 99 percent there so I hope I hope you can forgive me for not wasting any more of your time and just going through and trying to get it a hundred percent right but it's just actually going through here and just setting certain ones to false and making sure that all the states are all the states are agreed so but yeah it pretty much works and I hope I hope that you got some things out of that tutorial it's really been an educational for me and yeah so yeah I hope you I hope you enjoyed this tutorial if you got something out of it be sure to like it and I will see you next time
Info
Channel: The Audio Programmer
Views: 5,542
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, sample
Id: vVnu-L712ho
Channel Id: undefined
Length: 41min 15sec (2475 seconds)
Published: Sun May 27 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.