Audio Class

The Audio class is the real workhorse of the two classes, providing numerous methods to load and play samples. The Audio class provides a built-in sound manager that can store samples internally so you need not maintain global sample objects in your game’s code listing. You can load and play a sound from the Audio class in a “fire and forget” style of programming that is very easy to implement and use. On the other hand, there may be cases when you want to manage your own samples, and the Audio class supports that as well, with the ability to both load and play a sample using a Sample object that you provide.

There are some interesting methods in this class. You can play and stop a sample by name. (Yes, that’s right, using a string rather than an object!) The class also has the ability to stop all samples in the output buffer. During testing, I had a specific but unusual need to stop playback of all sounds except for one, and that spawned the StopAllExcept() method! Another interesting method is FindSample(), which will search through its internal list of samples (by name) and return a pointer to the Sample object. (Just remember that it points to the object in the audio manager, so you should not delete any sample retrieved in this way.)

Now, let’s see the definition for the Audio class found in Audio.h:

class Audio
{
private:
    FMOD_SYSTEM *system;
    typedef std::vector<Sample*> Samples;
    typedef std::vector<Sample*>::iterator Iterator;
    Samples samples;
public:
    Audio();
    ~Audio();
    FMOD_SYSTEM* getSystem() { return system; }
    bool Init();
    void Update(); //must be called once per frame
    bool Load(std::string filename, std::string name);
    Sample* Load(std::string filename);
    bool Play(std::string name);
    bool Play(Sample *sample);
    void Stop(std::string name);
    void StopAll();
    void StopAllExcept(std::string name);
    bool IsPlaying(std::string name);
    bool SampleExists(std::string name);
    Sample *FindSample(std::string name);
};

Finally, we come to the implementation of the Audio class, which does all of the real work. This class will make it very easy to load and play a sample. There’s a lot of C++ Standard Library code in here, so if you are not familiar with it, you might feel a bit lost. We’ll be using STL constructs even more in Chapter 7, “Entities,” while building an entity manager.

Audio::Audio()
{
    system = NULL;
}

Audio::~Audio()
{
    //release all samples
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        (*i) = NULL;
    }
    FMOD_System_Release(system);
}

bool Audio::Init()
{
    if (FMOD_System_Create(&system) != FMOD_OK) {
        return false;
    }
    if (FMOD_System_Init(system,100,FMOD_INIT_NORMAL,NULL) != FMOD_OK) {
        return false;
    }
    return true;
}

void Audio::Update()
{
    FMOD_System_Update(system);
}

Sample* Audio::Load(std::string filename)
{
    if (filename.length() = = 0) return false;

    Sample *sample = new Sample();
    FMOD_RESULT res;
    res = FMOD_System_CreateSound(
        system,             //FMOD system
        filename.c_str(),     //filename
        FMOD_DEFAULT,         //default audio
        NULL,                 //n/a
        &sample->sample);     //pointer to sample
    if (res != FMOD_OK) {
        sample = NULL;
    }
    return sample;
}

bool Audio::Load(std::string filename, std::string name)
{
    if (filename.length() = = 0 || name.length() = = 0) return false;
    Sample *sample = new Sample();
    sample->setName(name);
    FMOD_RESULT res;
    res = FMOD_System_CreateSound(
        system,             //FMOD system
        filename.c_str(),     //filename
        FMOD_DEFAULT,         //default audio
        NULL,                 //n/a
        &sample->sample);    //pointer to sample
    if (res != FMOD_OK) {
        return false;
    }
    samples.push_back(sample);
    return true;
}

bool Audio::SampleExists(std::string name)
{
     for (Iterator i = samples.begin(); i != samples.end(); ++i)
     {
         if ((*i)->getName() = = name) {
             return true;
         }
     }
     return false;
 }

 bool Audio::IsPlaying(std::string name)
 {
     Sample *samp = FindSample(name);
     if (samp = = NULL) return false;

     int index;
     FMOD_Channel_GetIndex(samp->channel, &index);
    // FMOD returns 99 if sample is playing, 0 if not
    return (index > 0);
}

Sample *Audio::FindSample(std::string name)
{
    Sample *sample = NULL;
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        if ((*i)->getName() = = name) {
            sample = (*i);
            break;
        }
    }
    return sample;
}


bool Audio::Play(std::string name)
{
    FMOD_RESULT res;
    Sample *sample = FindSample(name);
    if (sample->sample != NULL) {
        //sample found, play it
        res = FMOD_System_PlaySound(
            system,
            FMOD_CHANNEL_FREE,
            sample->sample,
            true,
            &sample->channel);

        if (res!= FMOD_OK) return false;
        FMOD_Channel_SetLoopCount(sample->channel, -1);
        FMOD_Channel_SetPaused(sample->channel, false);
    }
    return true;
}

bool Audio::Play(Sample *sample)
{
    FMOD_RESULT res;
    if (sample = = NULL) return false;
    if (sample->sample = = NULL) return false;
    res = FMOD_System_PlaySound(
        system,
        FMOD_CHANNEL_FREE,
        sample->sample,
        true,
        &sample->channel);

    if (res!= FMOD_OK) return false;
    FMOD_Channel_SetLoopCount(sample->channel, -1);
    FMOD_Channel_SetPaused(sample->channel, false);
    return true;
}

void Audio::Stop(std::string name)
{
    if (!IsPlaying(name)) return;
    Sample *sample = FindSample(name);
    if (sample = = NULL) return;
    FMOD_Channel_Stop(sample->channel);
}

void Audio::StopAll()
{
     for (Iterator i = samples.begin(); i != samples.end(); ++i)
     {
         FMOD_Channel_Stop( (*i)->channel );
     }
}

void Audio::StopAllExcept(std::string name)
{
     for (Iterator i = samples.begin(); i != samples.end(); ++i)
     {
         if ((*i)->getName() != name) {
             FMOD_Channel_Stop( (*i)->channel );
         }
     }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset