Sign in to follow this  
Stompy9999

FMOD: Multiple samples

Recommended Posts

In my game, I load two samples the way it shows in this article. However, when I start the program, one of my sounds plays over and over again, even though I didn't tell it to. The article says that something different needs to be done in order to play multiple samples. So, how do I load and play multiple samples without getting this problem?

Share this post


Link to post
Share on other sites
I noticed this a while ago when I was trying to get it working in C#. It seems that it keeps on looping if you're using the hardware device through FMOD. Try setting it to software and you'll see that it only plays once [smile].

Also, you might want to have a look at the work of Zahlman and I:

audio.h

#if !defined(_AUDIOSYSTEM_H_INCLUDED_)
#define _AUDIOSYSTEM_H_INCLUDED_

#include <string>
#include <map>

#include <FMOD/fmod.h>
#include <FMOD/fmod_errors.h> // optional




namespace System {

class AudioItem;
class MusicItem;
class SoundItem;

extern MusicItem* currentMusic;

class CAudio {
public:
CAudio();
~CAudio();


void Close(std::string filename);

void Stop();
bool Stop(std::string filename);
void StopMusic();
int MusicVolume(int volume);

bool Load(std::string name, std::string filename, int type = 0);
void Play(std::string filename);
void Pause(std::string filename, bool pause);
bool Pause(std::string filename);
void Looping(std::string filename, bool looping);
bool Looping(std::string filename);

void Volume(int volume);
int Volume();
void Volume(std::string filename, int volume);
int Volume(std::string filename);
};

extern CAudio Audio;


/*****************************************************************/
class AudioItem
{
public:
virtual ~AudioItem() { }
virtual void Play() = 0;
virtual void Stop() = 0;
virtual void Close() = 0;
virtual bool Load(std::string) = 0;

// These functions only exist in Music
virtual void Pause(bool pause){ }
virtual bool Pause(){ return false; }
virtual bool Looping(){ return false; }
virtual void Looping(bool looping){ }

virtual void Volume(int volume) { }
virtual int Volume() { return 100; }

int type;
};


/*****************************************************************/
class SoundItem : public AudioItem
{
public:
SoundItem() : channel(-1), handle(NULL) { }
bool Load(std::string filename){
handle = FSOUND_Sample_Load(
FSOUND_FREE|FSOUND_UNMANAGED,
filename.c_str(), 0, 0, 0);
return handle != NULL;
}
void Stop() { FSOUND_StopSound(channel); }
void Play() {
if(handle)
channel = FSOUND_PlaySound(FSOUND_FREE, handle);
}
void Close() {
if(handle){
Stop();
FSOUND_Sample_Free(handle);
handle = NULL;
}
}
~SoundItem() { Close(); }

FSOUND_SAMPLE* Handle(){ return handle; }
private:
FSOUND_SAMPLE* handle;
int channel;
};


/*****************************************************************/


class MusicItem : public AudioItem
{
public:
MusicItem() : looping(true), handle(NULL) { }
bool Load(std::string filename){
handle = FMUSIC_LoadSong(filename.c_str());
return handle != NULL;
}
void Close(){
Stop();
if(handle){
FMUSIC_FreeSong(handle);
handle = NULL;
}
}
~MusicItem(){ Close(); }
void Play() {
if(handle){
if(currentMusic){
FMUSIC_StopSong(currentMusic->Handle());
}
currentMusic = this;
FMUSIC_PlaySong(handle);
}
}
void Stop() {
if(handle){
FMUSIC_StopSong(handle);
currentMusic = NULL;
}
}
void Pause(bool pause) {
if(handle)
FMUSIC_SetPaused(handle, pause);
}
bool Pause() {
if(handle)
return FMUSIC_GetPaused(handle);
else
return false;
}
bool Looping(){ return looping; }
void Looping(bool looping){
if(handle){
FMUSIC_SetLooping(handle, looping);
this->looping = looping;
}
}

void Volume(int volume) {
if(handle)
FMUSIC_SetMasterVolume(handle, (int)(volume*2.55));
}
int Volume() {
if(handle)
return (int)(FMUSIC_GetMasterVolume(handle)/2.55);
else
return -1;
}

FMUSIC_MODULE* Handle(){ return handle; }
private:
FMUSIC_MODULE* handle;
bool looping;
};

/*****************************************************************/

class StreamItem : public AudioItem {
public:
StreamItem( ) : channel(-1), handle(NULL) { }
bool Load(std::string filename){
handle = FSOUND_Stream_Open(filename.c_str(),0, 0, 0);
return handle != NULL;
}
void Close(){
if(handle){
Stop();
FSOUND_Stream_Close(handle);
}
}
~StreamItem() { Close(); }
void Play() {
if(handle)
channel = FSOUND_Stream_Play(FSOUND_FREE, handle);
}
void Stop() {
if(handle)
FSOUND_Stream_Stop(handle);
}
FSOUND_STREAM* Handle(){ return handle; }
private:
FSOUND_STREAM* handle;
int channel;
};
/*****************************************************************/

}


#endif // _AUDIOSYSTEM_H_INCLUDED_






audio.cpp

#include "audio.h"

#include <string>
#include <map>
#include <cctype> // for toupper

#include <FMOD/fmod.h>
#include <FMOD/fmod_errors.h> // optional



namespace System {

std::map<std::string, AudioItem*> AudioData;
typedef std::map<std::string, AudioItem*>::iterator AudioDataItem;

MusicItem* currentMusic;
CAudio Audio;

AudioItem* get(std::string filename) {
AudioDataItem it = AudioData.find(filename);
if (it == AudioData.end()) return NULL;
return it->second;
}



CAudio::CAudio(){
if (FSOUND_GetVersion() < FMOD_VERSION){
//SDL_SetError("FMOD.DLL version is old, please update it.");
return;
}

if (!FSOUND_Init(32000, 64, 0)){
//SDL_SetError(FMOD_ErrorString(FSOUND_GetError()));
return;
}
//return true;
}

CAudio::~CAudio(){
Stop();
for(AudioDataItem pos = AudioData.begin(); pos != AudioData.end(); ++pos){
if(pos->second){
pos->second->Close();
delete pos->second;
}
}
AudioData.clear();
FSOUND_Close();
}

void CAudio::StopMusic(){
if(currentMusic)
currentMusic->Stop();
}

int CAudio::MusicVolume(int volume) {
for(AudioDataItem pos = AudioData.begin(); pos != AudioData.end(); ++pos){
if(pos->second){
if(pos->second->type == 2){
pos->second->Volume(volume);
}
}
}
return volume;
}

void CAudio::Close(std::string filename){
AudioItem* a = get(filename);
if(a){
a->Close();
AudioData.erase(filename);
}
}



bool CAudio::Load(std::string name, std::string filename, int type){
// Check if already exists
AudioDataItem it = AudioData.find(name);
if (it != AudioData.end())
return true; // Already loaded

// Get the type
if(type <= 0){
//TODO - Find what type it is
std::string fileExtension = "NONE";
if(filename.length() > 4)
fileExtension = filename.substr(filename.length() - 3, 3);

// Convert to uppercase
for (int i = 0; i < fileExtension.length(); i++ )
fileExtension[i] = toupper(fileExtension[i]);

if(fileExtension == "MOD" || fileExtension == "S3M" ||
fileExtension == ".XM" || fileExtension == ".IT" ||
fileExtension == "MID" || fileExtension == "IDI" ||
fileExtension == "RMI" || fileExtension == "SGT" ||
fileExtension == "FSB"){
type = 2; // Music
} else if(fileExtension == "WAV" || fileExtension == "MP2" ||
fileExtension == "MP3" || fileExtension == "OGG" ||
fileExtension == "RAW"){
type = 1; // Sound
} else {
type = 1; // Default
}
}

// Create the item that we'll be adding in
AudioItem* a;
switch(type){
case 1: a = new SoundItem(); break;
case 2: a = new MusicItem(); break;
case 3: a = new StreamItem(); break;
default: a = new SoundItem(); break;
}
if(a->Load(filename)){
AudioData[name] = a;
a->type = type;
return true;
} else {
delete a;
return false;
}
}


void CAudio::Play(std::string filename){
AudioItem* a = get(filename);
if(a != NULL)
a->Play();
}

bool CAudio::Stop(std::string filename){
AudioItem* a = get(filename);
if(a != NULL){
a->Stop();
return true;
}
}
void CAudio::Stop(){
for(AudioDataItem pos = AudioData.begin(); pos != AudioData.end(); pos++){
if(pos->second){
pos->second->Stop();
}
}
}


void CAudio::Pause(std::string filename, bool pause){
AudioItem* a = get(filename);
if(a != NULL)
a->Pause(pause);
}
bool CAudio::Pause(std::string filename){
AudioItem* a = get(filename);
if(a != NULL)
return a->Pause();
}


void CAudio::Looping(std::string filename, bool looping){
AudioItem* a = get(filename);
if(a != NULL)
a->Looping(looping);
}
bool CAudio::Looping(std::string filename){
AudioItem* a = get(filename);
if(a != NULL)
return a->Looping();
}

void CAudio::Volume(int volume){
if(volume<0) volume = 0;
else if(volume>100) volume = 100;
FSOUND_SetSFXMasterVolume((int)(volume*2.55));
}
int CAudio::Volume(){
return (int)(FSOUND_GetSFXMasterVolume()/2.55);
}

void CAudio::Volume(std::string filename, int volume){
AudioItem* a = get(filename);
if(a != NULL)
return a->Volume(volume);
}

int CAudio::Volume(std::string filename){
AudioItem* a = get(filename);
if(a != NULL)
return a->Volume();
}







}




Usage:
System::Audio.Load("SomeSound", "sound.wav");
System::Audio.Load("SomeMusic", "music.mid");
System::Audio.Play("SomeSound");
// ... etc.

There might be a few bugs around as I just copied it directly from the Blastoids source.

Share this post


Link to post
Share on other sites
How exactly do I set it to software?

On an unrelated note, that is from Lucid right? Is work still being done on this engine? I became interested in it after looking at the Blastoids source.

Thanks again.

Share this post


Link to post
Share on other sites
Nope, I'm not continuing it. I got fed up with the endless development of the engine so I decided to turn it into the asteroids clone. But the source for Lucid is still in there as Blastoids uses it completely so if you want to have a look, feel free to do so. After trying out C#, I realized its power over C++ and am using it primarily now [smile].

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this