如何让Fmod在课堂上工作?

时间:2015-02-01 21:49:07

标签: c++ fmod

在我用C ++编写的项目中,我FMOD目前正在使用main.cpp。为了帮助组织我的引擎,我想将我的声音代码移动到它自己的翻译单元。出于某种原因,当我尝试从课堂上运行我的声音代码时,它没有播放任何声音。我不确定是不是因为错误的价值分配,或者是否存在我不了解的更大问题。这是我的类实现:

//Sound.h
#ifndef SOUND_H
#define SOUND_H

#include <iostream>

#include "inc\fmod.hpp"
#include "inc\fmod_errors.h"

class Sound
{
public:
    Sound(void);
    ~Sound(void);

    void Init();
    void FMODErrorCheck(FMOD_RESULT res);

    void PlaySound();
    void ResumeSound();
    void PauseSound();

    void Update();

private:
    //sound
    FMOD::System    *sys;
    FMOD_RESULT result;
    size_t  version; //this is just an unsigned int
    FMOD_SPEAKERMODE speakerMode;
    int numDrivers;
    FMOD_CAPS caps;
    char    name[256];
    FMOD::Sound *sound;
    FMOD::Channel *channel;
    bool    quitFlag;
};

#endif


//Sound.cpp
#include "Sound.h"

Sound::Sound(void)
{
    Init();
}

Sound::~Sound(void)
{
    FMODErrorCheck(sound->release());
    FMODErrorCheck(sys->release());
}

void Sound::Init()
{
    // Create FMOD interface object
    result = FMOD::System_Create(&sys);
    FMODErrorCheck(result);

    // Check version
    result = sys->getVersion(&version);
    FMODErrorCheck(result);

    if(version < FMOD_VERSION)
    {
        std::cout << "Error! You are using an old version of FMOD " << version << ". This program requires " << FMOD_VERSION << std::endl;
        exit(0);
    }

    // Get number of sound cards
    result = sys->getNumDrivers(&numDrivers);
    FMODErrorCheck(result);

    // No sound cards (disable sound)
    if(numDrivers == 0)
    {
        result = sys->setOutput(FMOD_OUTPUTTYPE_NOSOUND);
        FMODErrorCheck(result);
    }

    // At least one sound card
    else
    {
        // Get the capabilities of the default (0) sound card
        result = sys->getDriverCaps(0, &caps, 0, &speakerMode);
        FMODErrorCheck(result);

        // Set the speaker mode to match that in Control Panel
        result = sys->setSpeakerMode(speakerMode);
        FMODErrorCheck(result);

        // Increase buffer size if user has Acceleration slider set to off
        if(caps & FMOD_CAPS_HARDWARE_EMULATED)
        {
            result = sys->setDSPBufferSize(1024, 10);
            FMODErrorCheck(result);
        }

        // Get name of driver
        result = sys->getDriverInfo(0, name, 256, 0);
        FMODErrorCheck(result);

        // SigmaTel sound devices crackle for some reason if the format is PCM 16-bit.
        // PCM floating point output seems to solve it.
        if(strstr(name, "SigmaTel"))
        {
            result = sys->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
            FMODErrorCheck(result);
        }
    }

    // Initialise FMOD
    result = sys->init(100, FMOD_INIT_NORMAL, 0);

    // If the selected speaker mode isn't supported by this sound card, switch it back to stereo
    if(result == FMOD_ERR_OUTPUT_CREATEBUFFER)
    {
        result = sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
        FMODErrorCheck(result);

        result = sys->init(100, FMOD_INIT_NORMAL, 0);
    }
    FMODErrorCheck(result);

    // Open music as a stream
    //FMOD::Sound *song1, *song2, *effect;
    //result = sys->createStream("Effect.mp3", FMOD_DEFAULT, 0, &sound);
    //FMODErrorCheck(result);

    result = sys->createSound("Effect.mp3", FMOD_DEFAULT, 0, &sound);
    FMODErrorCheck(result);

    // Assign each song to a channel and start them paused
    //result = sys->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
    //FMODErrorCheck(result);

    // Songs should repeat forever
    channel->setLoopCount(-1);
}

void Sound::FMODErrorCheck(FMOD_RESULT res)
{
    if(res != FMOD_OK)
    {
        std::cout << "FMOD ERROR: (" << res << ") - " << FMOD_ErrorString(res) << std::endl;
        //quitFlag = true;
    }
}

void Sound::PlaySound()
{
    sys->playSound(FMOD_CHANNEL_FREE, sound, false, 0);
}

void Sound::ResumeSound()
{
    channel->setPaused(false);
}

void Sound::PauseSound()
{
    channel->setPaused(true);
}

void Sound::Update()
{
    sys->update();
}


//Main.cpp
Sound sound;

// Initialization routine.
void setup(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);

    sound = &Sound();
}

//------------------------------------------------------------ OnInit()
//
void OnIdle()
{
    if(IsKeyPressed(KEY_ESCAPE))
    {
        exit(EXIT_SUCCESS);
    }

    if(IsKeyPressed('1'))
    {
        sound->PlaySound();
    }

    sound->Update();

    // redraw the screen
    glutPostRedisplay();
}

目前它给了我2个错误:

Unhandled exception at 0x0F74465A (fmodex.dll) in TestOpenGL.exe: 0xC0000005: Access violation reading location 0x062C5040

FMOD error! (36) An invalid object handle was used

知道它为什么不起作用?知道我如何解决这些问题吗?

2 个答案:

答案 0 :(得分:0)

从您上次发表评论并查看代码后,我发现了一个问题。您已经按FMOD::System *sys;创建了一个指针,但此指针未初始化为FMOD::System的任何实例,即代码中的某处应该有sys = new FMOD::Systemsys = new FMOD::System(/* whatever argument you must supply to it's constructor */);这样的内容在您尝试访问与FMOD::System对象相关的任何内容之前。这很可能是程序崩溃的原因。此外,由于sys是指向FMOD::System的指针,因此在包含result = FMOD::System_Create(&sys);的行中存在另一个问题,即您通过引用传递指针。我建议你阅读一些关于C和C ++指针的文章,还有一些关于面向对象编程语言中的对象创建和破坏的文章。

答案 1 :(得分:0)

我能够帮助解决这个问题。我错误地初始化了我的声音变量。

sound = &Sound();

实际应该是:

sound = new Sound();