快板 5 一次播放多个样本

Allegro 5 Play Multiple Samples at Once

本文关键字:播放 样本 一次 快板      更新时间:2023-10-16

我在播放样本 Allegro 5 时遇到了一个问题。当我播放样本时,在播放完之前,我无法再次播放该样本。有时,如果正在播放另一个不同的样本,它也不会播放样本。

无论如何要解决这个问题?

我使用"声音"类播放音频,该类只有一个播放功能。其余的是构造器和成员变量,所有这些都用于播放函数。

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
}

全班:

声音.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();
};

声音.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 返回等)。

如果我需要澄清任何事情,请告诉我。任何帮助总是不胜感激的。

我可能是错的,但听起来你必须使用al_reserve_samples(number_of_samples);保留更多样本

根据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);