Allegro 5一次播放多个样本

时间:2016-03-03 04:14:50

标签: c++ audio allegro5

我遇到了播放样本Allegro 5的问题。当我播放样本时,我不能再播放该样本,直到它完成播放。如果播放另一个不同的样本,有时它也不会播放样本。

无论如何要绕过这个?

我使用“Sound”类播放音频,该类只有播放功能。其余的是构造函数和成员变量,所有这些都在play函数中使用。

void Sound::play()
{
    al_play_sample(
        pSample,    // ALLEGRO_SAMPLE
        mGain,      // float
        mPan,       // float
        mSpeed,     // float
        getPlaymode(mPlaymode), // I use my own non-AL playmode enums. This is a private function that returns the AL version.
        NULL);      // ALLEGRO_SAMPLE_ID
}

全班:

Sound.h

class ContentManager;

enum Playmode
{
    BiDir,
    Loop,
    Once,
    StreamOnce,
    StreamOneDir
};

class Sound : public Trackable
{
private:
    /*  Variables
    * * * * * * * * * * * * */
    ALLEGRO_SAMPLE* pSample;

    float
        mGain,
        mPan,
        mSpeed;

    Playmode mPlaymode;

    std::string
        mAssetPath,
        mAssetName;

    /*  Private Functions
    * * * * * * * * * * * * */
    ALLEGRO_PLAYMODE getPlaymode(Playmode playmode)
    {
        switch (playmode)
        {
            case BiDir:
                return ALLEGRO_PLAYMODE::ALLEGRO_PLAYMODE_BIDIR;

            case Loop:
                return ALLEGRO_PLAYMODE::ALLEGRO_PLAYMODE_LOOP;

            case Once:
                return ALLEGRO_PLAYMODE::ALLEGRO_PLAYMODE_ONCE;

            case StreamOnce:
                return ALLEGRO_PLAYMODE::_ALLEGRO_PLAYMODE_STREAM_ONCE;

            case StreamOneDir:
                return ALLEGRO_PLAYMODE::_ALLEGRO_PLAYMODE_STREAM_ONEDIR;

            // Default to once
            default:
                return ALLEGRO_PLAYMODE::ALLEGRO_PLAYMODE_ONCE;
        }
    }

public:
    /*  Constructors/Destructor
    * * * * * * * * * * * * */
    Sound();

    Sound(
        // assetPath, assetName, gain, pan, speed, playmode
        std::string assetPath, 
        std::string assetName, 
        float gain = 1.0f, 
        float pan = 0.0f, 
        float speed = 1.0f,
        Playmode playmode = Once);

    Sound(const Sound& other);

    ~Sound();

    friend class ContentManager; // My content system.

    void play();

};

Sound.cpp

#include "Sound.h"

/*  Constructors/Destructor
* * * * * * * * * * * * */
Sound::Sound()
{
    this->mAssetPath = "";
    this->mAssetName = "";
    this->mGain = 1.0f;
    this->mPan = 0.0f;
    this->mSpeed = 1.0f;
    this->mPlaymode = Once;

    this->pSample = NULL;
}

Sound::Sound(std::string assetPath, std::string assetName, float gain, float pan, float speed, Playmode playmode)
{
    this->mAssetPath = assetPath;
    this->mAssetName = assetName;
    this->mGain = gain;
    this->mPan = pan;
    this->mSpeed = speed;
    this->mPlaymode = playmode;

    this->pSample = al_load_sample((assetPath + assetName).c_str());
}

Sound::Sound(const Sound& other)
{
    this->mAssetPath = other.mAssetPath;
    this->mAssetName = other.mAssetName;    
    this->mGain = other.mGain;
    this->mPan = other.mPan;
    this->mSpeed = other.mSpeed;
    this->mPlaymode = other.mPlaymode;

    this->pSample = al_load_sample((mAssetPath + mAssetName).c_str());
}

Sound::~Sound()
{
    al_destroy_sample(pSample);
}


void Sound::play()
{
    al_play_sample(
        pSample,
        mGain,
        mPan,
        mSpeed,
        getPlaymode(mPlaymode),
        NULL);
}

我通过系统的其余部分调用play功能,看起来像这样:

// Game->ContentManager->Sound->play()
Game::instance()->content()->getSound("somesound.wav")->play();

内容管理器包含我的资产的地图。

这是我正在为一个班级工作的一个大项目的一部分,但不,这部分不是作业。我的教授不允许我们使用任何公共/顶级AL代码(例如没有公共AL返回等)。

如果我需要澄清任何事情,请告诉我。任何帮助总是受到赞赏。

2 个答案:

答案 0 :(得分:0)

我可能错了,但听起来你必须使用al_reserve_samples(number_of_samples);

保留更多样本

答案 1 :(得分:0)

根据ppsz的回答,我做了一些挖掘,并根据我发现的内容做了以下工作。

int numSamples = /*Some int*/
int reservedSamples = 0;
int i = (numSamples >= 1 ? numSamples : 1);
bool success = false;

do
{
    success = al_reserve_samples(i);

    i -= 1;
}
while (success == false || i > 0);

Source