FMOD: Multiple samples
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?
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
audio.cpp
Usage:
There might be a few bugs around as I just copied it directly from the Blastoids source.
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.
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.
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.
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].
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement