FMOD: Multiple samples

Started by
2 comments, last by Rob Loach 18 years, 10 months ago
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?
-----------------------------Play Stompy's Revenge! Now!
Advertisement
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> // optionalnamespace 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> // optionalnamespace 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 = toupper(fileExtension);			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.
Rob Loach [Website] [Projects] [Contact]
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.
-----------------------------Play Stompy's Revenge! Now!
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].
Rob Loach [Website] [Projects] [Contact]

This topic is closed to new replies.

Advertisement