The Red Penguin

Writing the DJAudioPlayer class


Friday 31 July 2020

This class will have a number of public functions we have already set up - loadURL, setGain, setSpeed, setPosition, start and stop.

1. We need to inherit from the Juce library. To do this go to MainComponent.h and get the code which includes it - #include - and paste this into DJAudioPlayer.h

2. In the header file, we need to define the class.
class DJAudioPlayer {

};

3. We need to add the inheritance relationship, which is the audio source. So change this to:
class DJAudioPlayer : public juce::AudioSource {

};


I added the juce:: - he didn't add this but I think it's right to include it.

AudioSource has these pure virtual functions that we have to implement, which we have in our MainComponent class. So we copy and paste this from MainComponent.h, remembering to type public: too ...
    public:
//==============================================================================
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override;
void getNextAudioBlock(const juce::AudioSourceChannelInfo& bufferToFill) override;
void releaseResources() override;

4. The tutor says - I'm probably going to need a constructor - I think we always do in a new class? He also said "I'll add a destructor as well". So just below public: in DJAudioPlayer.h we add this:
DJAudioPlayer();
~DJAudioPlayer();

5. We need to add the real interface - the one we're interested in. He means the list of function names up above! So in public: we add ...
        void loadURL(juce::URL audioURL);
void setGain(double gain);
void setSpeed(double ratio);
void setPosition (double posInSecs);
void start();
void stop();

6. This is the basic class defined. The next step is to get to the point where we can compile this thing. So we need to go into the DJAudioPlayer.cpp file and write quick empty implementations of all of these functions.

We copy the public: code from the new .h and paste into the new .cpp. We have to prefix all of the function names with DJAudioPlayer:: and then remove the semicolons and put brackets in. We can also get rid of any "override" because we don't need that in the .cpp implementation. So this is what the new .cpp file looks like:
#include "DJAudioPlayer.h"

DJAudioPlayer::DJAudioPlayer()
{

}

DJAudioPlayer::~DJAudioPlayer()
{

}

//==============================================================================
void DJAudioPlayer::prepareToPlay(int samplesPerBlockExpected, double sampleRate)
{

}

void DJAudioPlayer::getNextAudioBlock(const juce::AudioSourceChannelInfo& bufferToFill)
{

}

void DJAudioPlayer::releaseResources()
{

}

void DJAudioPlayer::loadURL(juce::URL audioURL)
{

}

void DJAudioPlayer::setGain(double gain)
{

}

void DJAudioPlayer::setSpeed(double ratio)
{

}

void DJAudioPlayer::setPosition(double posInSecs)
{

}

void DJAudioPlayer::start()
{

}

void DJAudioPlayer::stop()
{

}

7. We need to put an instance of this object into the MainComponent.h. We go to this file and add:
#include "DJAudioPlayer.h"

8. At the end of MainComponent.h in the private: section we need to create an instance of it. So we type:
DJAudioPlayer player1;

Now we can build and compile and it works! We went through and implemented the basic top level functionality that we were hoping to have in our DJAudioPlayer.

I started out by adding a new file to Projucer. Then I put all the functions I needed in there I implemented the class inheritance from AudioSource because these things going to generate audio. And then I went through, put all the top level functions that I want in there as well as the AudioSource interface requirements. And at the end, I went into empty functions for everything into my CPP file, ready to be filled up with lots of fun code which I'm going to actually take from the main component.