-1

In my project written in C++, I have FMOD currently working from my main.cpp. To help organize my engine I want to move my sound code to it's own translation unit. For some reason when I try to run my sound code from within my class, it doesn't play any sound. I'm not sure if it is because of incorrect assignment of the value or if there is a bigger issue that I don't know about. This is my class implementation:

//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();
}

Currently it is giving me 2 errors:

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

and

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

Any idea why it isn't working? Any idea how I solve these issues?

max
  • 2,627
  • 1
  • 24
  • 44
WhyYouNoWork
  • 273
  • 5
  • 18
  • are you using a library or you only wrote the code of the headers you have included? It's difficult to say without knowing what it does and how it is implemented. – max Feb 01 '15 at 21:57
  • @Barracuda The only library it should include is from fmod. It is just suppose to play sound using fmod. This is a cut down version of my code to how I implemented it: http://ideone.com/Nkyr3R. This is how my sound code is in my main right now that works: http://ideone.com/GBjrYA. I can't figure out why it doesn't work in my class though, but it does work in my main. – WhyYouNoWork Feb 01 '15 at 22:23
  • Please clarify "..why it isn't working". Is it a compiler error, linker error, or run-time error? – Thomas Matthews Feb 01 '15 at 22:23
  • @ThomasMatthews I think it more falls under a logic error. The program doesn't break, but it doesn't do what I want. As I stated in my question it won't play sound using my code from my class and I can't figure out why. This is a cut down version of how I call my class in my main: http://ideone.com/Nkyr3R – WhyYouNoWork Feb 01 '15 at 22:30
  • 1
    @WhyYouNoWork you are basically asking others to fix your code for you. You can find out the reason by using a debugger and testing the values of your objects to see if they are initialized to / assigned with proper values. – max Feb 01 '15 at 22:30
  • @Barracuda Isn't the point of StackOverflow to get help with coding? I don't know why it doesn't work which is why I'm asking. I don't know Fmod very well so all the values associated with Fmod shows very odd values which I don't understand. – WhyYouNoWork Feb 01 '15 at 22:43
  • @WhyYouNoWork not in your case. There's an amazing tool called "debugger" that you must setup and use to solve your particular case and narrow down your question to the exact point where the problem occurs. Also there's probably a mailing list for the library you are using that you can subscribe to and ask technical questions about the setup required for it to work. And remember to use a search engine to find the answer before asking on stackoverflow. – max Feb 01 '15 at 23:05
  • @Barracuda If I understood it I wouldn't be asking. I can't find any info on my issue. There are a lot of people out there who understand fmod better than I do and I was hoping someone would give a valid answer. Looking through debugger I only get garbage data. Do you understand fmod at all? If so maybe you can explain this error which yeilds no results in Google: Unhandled exception at 0x0F74465A (fmodex.dll) in TestOpenGL.exe: 0xC0000005: Access violation reading location 0x062C5040. – WhyYouNoWork Feb 05 '15 at 21:28
  • @WhyYouNoWork good! now there's the problem. when you ask question you should include the error you get. If there's anyone who has had the same issue and found out how to solve it then they can help you. Your program has thrown an exception and that and it looks like you have tried to dereference a pointer / access a location that does not exist in the memory. This is not an `FMOD` problem this is a general error that could rise due to improper instantiation or improper access. – max Feb 05 '15 at 22:31

2 Answers2

0

From your last comment and looking at your code I see a problem. You have created a pointer by FMOD::System *sys; but this pointer is not initialized to any instance of FMOD::System that is, there should be something like sys = new FMOD::System or sys = new FMOD::System(/* whatever argument you must supply to it's constructor */); somewhere in your code but right before you try to access anything related to FMOD::System object. This is most probably the reason for your program crash. Also since sys is a pointer to FMOD::System there's another problem at line containing result = FMOD::System_Create(&sys); you are passing a pointer by reference. I suggest you read a couple of articles about pointers in C and C++ and also some more about object creation and destruction in object oriented programming languages.

max
  • 2,627
  • 1
  • 24
  • 44
  • I tried to set a value for sys in my constructor as you suggested, but it will not allow me to. it says that FMOD::System() is inaccessible. Any other suggestions? I also have another error that has apeared when I run the update. It says "FMOD error! (36) An invalid object handle was used." Any idea why this appears? It says online that I am trying to call a sound that ended, but I don't believe it calls a sound to begin with. – WhyYouNoWork Feb 05 '15 at 23:03
  • is `FMOD::System` singleton? – max Feb 05 '15 at 23:05
  • @WhyYouNoWork It could be due to `FMOD::System` constructor being private so you should find what function returns an instance to `FMOD::System` in the API documentation. The class might be following singleton design pattern. In such classes there's a function that returns a reference to an instance of the object for example there could be a function named `FMOD::System::getInstance()` or `FMOD::System::create()`. By the way, please update your question description and include the error message. – max Feb 05 '15 at 23:12
  • @WhyYouNoWork did you read [this](http://www.fmod.org/documentation/#content/generated/overview/getting_started.html)? It's clearly stated how you should initialize and use `System`. – max Feb 05 '15 at 23:30
  • I took a look at that page you sent me. I already have that in there. I added the system = NULL, but there was no change. – WhyYouNoWork Feb 06 '15 at 00:53
0

I was able to get help with the issue. I was initializing my sound variable incorrectly.

sound = &Sound();

Should actually be:

sound = new Sound();

WhyYouNoWork
  • 273
  • 5
  • 18