Thread: FMOD implimentation, how'd you do it?

  1. #1
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704

    FMOD implimentation, how'd you do it?

    I've just finnished implimenting FMOD into my summer project. It's pretty simple(I think) but it gets the job done. Showboat here about your FMOD , or any other MUSIC api implimentations.

    Feel free to comment on mine, or any others (daring enough who) posted.

    PS: as you can see, my music.cpp isn't actually finished. I left a couple functions empty for quick testing purposes. I'm filling them in now, but i'm sure you get the idea of their structure.

    This is the class files
    Code:
    //////////////////////////////////////////////////
    /********MUSIC.H***************/
    /////////////////////////////////////////////////
    #ifndef PR_MUSIC
    #define PR_MUSIC
    
    #include "global.h"
    #include "fmod.h"
    
    #define MAX_CHANNELS 32
    typedef enum AUDIOTYPE { AT_SONG, AT_SAMPLE, AT_STREAM };
    
    class FMODAudio {
    public:
    	FMODAudio( AUDIOTYPE type, bool loop );
    	~FMODAudio();
    
    public:
    	void LoadFile(char* filename);
    	void Play();
    	void Stop();
    	void SetVolume(int volume);
    	void Pause();
    private:
    	AUDIOTYPE m_type;
    	FMUSIC_MODULE* m_SoHandle; // .MOD, .S3M, .XM, .IT, .MID, .RMI, .SGT or .FSB 
    	FSOUND_STREAM* m_StHandle; // .WAV, .MP2, .MP3, .OGG or .RAW
    	FSOUND_SAMPLE* m_SaHandle; // .WAV, .MP2, .MP3, .OGG or .RAW
    	
    	int m_id; // what channel should this use (if it does)
    	bool m_loop; 
    
    public: // class management
    	static bool sm_channels[MAX_CHANNELS]; // what channels are being used?
    };
    
    #ifdef NEED_PR_MUSIC
    	bool FMODAudio::sm_channels[32];
    #endif
    
    // initialization function prototype
    void FMODAudioInit();
    
    
    #endif
    
    //////////////////////////////////////////////////
    /********MUSIC.CPP*************/
    /////////////////////////////////////////////////
    #define NEED_PR_MUSIC
    
    #include "global.h"
    #define MAX_CHANNELS 32
    
    FMODAudio::~FMODAudio() {
    	// clean up
    	// use appropriate function
    	// based on sound type
    	switch(m_type) 
    	{
    	case AT_SAMPLE:
    		FSOUND_Sample_Free(m_SaHandle);
    		break;
    	case AT_SONG:
    		FMUSIC_FreeSong(m_SoHandle);
    		break;
    	case AT_STREAM:
    		FSOUND_Stream_Close(m_StHandle);
    		break;
    	default:
    		break;
    	}
    	sm_channels[m_id] = true; // make channel available for new instances
    };
    
    FMODAudio::FMODAudio(AUDIOTYPE type, bool loop) {
    	m_type = type; // what kind of audio is it?
    	m_loop = loop; // does sound loop until told to stop?
    	for(int i = 0; i < MAX_CHANNELS; i++) {
    		// find a channel that is available
    		if( sm_channels[i] ) {
    			sm_channels[i] = false; // set it no longer available
    			m_id = i; // and assign id to this class instance
    			break;
    		}
    	}
    };
    
    ////////////////////
    // loads sound file
    void FMODAudio::LoadFile(char *filename) {
    	// use appropriate function
    	// for the sound type
    	switch(m_type){
    	case AT_SONG:
    		m_SoHandle = FMUSIC_LoadSong(filename);
    		break;
    	case AT_SAMPLE:
    		m_SaHandle = FSOUND_Sample_Load (m_id,filename,0,0,0);
    		break;
    	case AT_STREAM:
    		m_StHandle = FSOUND_Stream_Open(filename, 0, 0, 0);
    		break;
    	}
    };
    
    ////////////////////
    // play loaded sound
    void FMODAudio::Play() {
    	// use appropriate function
    	// for the sound type
    	switch(m_type)
    	{
    	case AT_SONG:
    		FMUSIC_SetLooping (m_SoHandle, m_loop); // set looping condition
    		FMUSIC_PlaySong(m_SoHandle); // play it
    		break;
    	case AT_SAMPLE:
    		FSOUND_PlaySound (m_id,m_SaHandle);
    
    		break;
    	case AT_STREAM:
    		FSOUND_Stream_Play (m_id,m_StHandle);
    		break;
    	}
    };
    
    void FMODAudio::Stop() {};
    
    void FMODAudio::Pause() {};
    
    void FMODAudio::SetVolume(int volume) {};
    
    
    void FMODAudioInit() {
    	for(int i = 0; i < MAX_CHANNELS; i++ ) {
    		FMODAudio::sm_channels[i] = true;
    	}
    }
    And then any where you Init,
    Code:
    	// FMOD INITIATION
    	FSOUND_Init (44100, 32, 0);
    	FMODAudioInit();
    
                    // construct sound object
    	FMODAudio *music = new FMODAudio(AT_STREAM, true);
    	music->LoadFile("data/music/05.mp3");
    	music->Play();
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  2. #2
    "The Oldest Member Here" Xterria's Avatar
    Join Date
    Sep 2001
    Location
    Buffalo, NY
    Posts
    1,039
    your a pretty talented programmer. I never cared for fmod because i have my simple mcisendstring

  3. #3
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    Your implementation looks pretty cool. I like how it's all encapsulated in to one class, simplifies things quite a bit.

    here's my fmod implementation, i chose to separate each part of fmod in to a separate class:

    Purposely only including the .h file, because otherwise this post'll be insanely huge, if you really want to see the .cpp's, just pm me and i'll post 'em here
    Code:
       #ifndef CFMOD_H_
       #define CFMOD_H_
       
       /***********************************************************\
       *
       *	cFmod classes
       *
       *	Coded by:
       *		Jeff Verkoeyen
       *
       *	Code versions:
       *		1.0 (5/17/2004)
       *		-Encapsulates the fmod API functions for streams
       *			and sounds.
       *
       *	Contact:
       *	  Email- [email protected]
       *	  Website- http://www.TheJeffFiles.com/
       *
       \***********************************************************/
       
       #pragma comment(lib, "fmodvc.lib")
       
       #include "fmod.h"
       
       // Must be called before doing anything with Fmod, or it will not work
       //  correctly!
       void cFMODInitSystem();
       void cFMODInitSystem(int mixrate,int maxsoftwarechannels,unsigned int flags);
       void cFMODCloseSystem();
       void cFMODSetGlobalVolume(unsigned char volume);
       
       class cFmodBase
       {
       protected:
       	int channel;
       	unsigned char volume;
       public:
       	void Stop();
     	void SetFrequency(int freq);		 // 100 to 705600, -100 to -705600
     	void SetLooping(int loopOn);			// True/False
     	void SetMute(int muteOn);			 // True/False
     	void SetPan(int side);				 // 0-255	0 Full Left, 255 Full Right
     	void SetPaused(int pauseOn);			// True/False
       	void SetSurround(int surroundOn);		// True/False
       	void SetVolume(unsigned char volume);	// 0-255
     	void SetPosition(unsigned int pos);		// Position in the song in samples
       
       	unsigned int GetPosition();
       	int isPlaying();
       };
       
       // Small files to be played multiple times
       //  Gets loaded in to RAM
       class cFmodSoundSample : public cFmodBase
       {
       private:
       	FSOUND_SAMPLE* samplePtr;
       public:
       	cFmodSoundSample();
       
       	int Load(char* fileName,unsigned int index=FSOUND_FREE);
       	void Play(int channel=FSOUND_FREE,int paused=0);
       	void Free();
       };
       
       // Bigger files that will loop or only need to be played once
       class cFmodSoundStream : public cFmodBase
       {
       private:
       	FSOUND_STREAM* streamPtr;
       public:
       	cFmodSoundStream();
       
       	int Load(char* fileName);
       	void Play(int channel=FSOUND_FREE,int paused=0);
       	void Free();
       
       	int GetSize();
       	int GetLength();
       
       // FSOUND_LOOP_NORMAL for looping
       	void SetMode(int mode);
       
       	void SetTime(int timeMS);
       };
       
       #endif
    Last edited by jverkoey; 06-09-2004 at 07:44 PM.

  4. #4
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    I wonder, does fmod have a specific 3d sound function, or do you have to come up with one yourself? I've figured out a quick way to do it yourself just by reading the member function names of your class lol. The setPan. Using cos/sin functions and an objects vector position, you could set the pan, and volume levels to simmulate 3d sound.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  5. #5
    Banned
    Join Date
    May 2004
    Posts
    129
    no, fmod comes with built-in 3D functions.

    I could show you an implementation, if you so kindly ask for it, but you should just research in the API documentation, like a good programmer (it's really not that hard to find, there's a section on 3D).

    The only thing I've had problems with was the unit convertor (so it knows how many units is a metre), because in the latest implementation of FMOD it essentially does not work.

    Looks good otherwise, should provide basic functionality for you, keep it up.
    Last edited by vNvNation; 06-10-2004 at 09:25 AM.

  6. #6
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    Yeah, I can find it myself. I just hadn't looked yet. I just found it interesting that by reading the word "setpan()" I in a split second developed a method to create 3d sound. It made me feel happy

    JV, I was wondering how you actually coded the base class. All the functions for volume and stuff are different functions calls per audio type that fmod utilizes. I was thinking that all the base functions would have to be virtual, so they could be defined by each inherited class for stream, song, and sample thus providing for a nice abstract interface for all your sound objects.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  7. #7
    Software Developer jverkoey's Avatar
    Join Date
    Feb 2003
    Location
    New York
    Posts
    1,905
    i mainly wrote the functions in the base fmod class just to work with the channels. I realized a bit late in to the implementation that some of the channel functions only work for certain audio types, hehe. For the most part they seem to work though.

    I uploaded my cFmod class if you wanna see the rest of the stuff

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    All of the above can be accomplished easy enough without FMOD and DirectAudio ships with 3D audio support as well as supporting nearly infinite groups of pchannels, performances, and separate audio paths complete with DMOs and special effects. It's quite simple to use and you are not bound to any specific implementation.

    For 3D sound you simply create a mono 3D audio path (stereo 3D audiopaths are not supported by DirectAudio as of DX9) and then play the sound. As you play the sound you can set both the position of the listener and the audiopath and the doppler effect is already computed for you, but you are allowed to alter it at will. This can be done in about 5 lines of C++ code.

  9. #9
    Banned
    Join Date
    May 2004
    Posts
    129
    FMOD encapsulates DirectSound.

    More specifically, it encapsulates DirectSound 3D, along with various other sound libraries, through an easy interface (API).

    That is all that FMOD is. So, if you've implemented FMOD, you have implemented at least DirectSound/DirectSound 3D.
    Last edited by vNvNation; 06-11-2004 at 03:57 PM.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    But to me since the underlying structure could simply be encapsulated in one or two classes, I see no need for FMOD. DirectAudio is so straightforward that only a few interfaces are needed to fire it up. It really is quite simple and an API or 3rd party code library here would only serve to complicate things IMO.

    But whatever the case I guess all that matters is the end product not how you get there. Should we all choose to get there through different routes doesn't change the fact that we are all trying to accomplish the same thing.

    So....with that...I rest my case.

  11. #11
    Banned
    Join Date
    May 2004
    Posts
    129
    I don't particularly care either way.

    The reason I don't care is that whatever route you take, you aren't forced to implement the underlying routines that send the proper electrical impulses (all based on complex physical/mathematical models) that vibrate your speakers to produce this human concept commonly known as "sound". That is, afterall, the purpose of using an API such as this. This is similar to our rendering APIs (Direct3D, OpenGL, SDL, FirePortion3D, and ManaLIB to name a few) which encapsulate the procedures for making the lights/pixels on your screen appear a certain color to produce what humans call "graphics".

    If we continue this discussion further we will ultimately only be arguing about how we organize the work that someone else has already done for us.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Incorrect results from fmod()?
    By karlthetruth in forum C Programming
    Replies: 4
    Last Post: 04-11-2008, 09:12 AM
  2. fmod()
    By salvadoravi in forum C Programming
    Replies: 1
    Last Post: 01-21-2008, 06:55 AM
  3. FMOD Decides it doesn't want to...
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 02-16-2006, 06:39 AM
  4. error with fmod() function
    By minesweeper in forum C++ Programming
    Replies: 3
    Last Post: 08-30-2003, 05:24 AM
  5. Fmod and windows programming
    By AtomRiot in forum Windows Programming
    Replies: 1
    Last Post: 01-06-2003, 03:13 PM