Sign in to follow this  

FMOD: Multiple samples

This topic is 4558 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

This topic is 4558 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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