From 68c918864f7dcb16c79b681040ac087b299a8c6d Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Tue, 26 Sep 2006 17:24:35 +0000 Subject: [PATCH] Fixes to fmod and scene editor --- doc/SceneEditor/collisionWindow.py | 1 + doc/SceneEditor/lightingPanel.py | 2 +- doc/SceneEditor/seMopathRecorder.py | 1 + panda/src/audio/audioManager.h | 105 +++-- panda/src/audiotraits/fmodAudioDSP.cxx | 30 +- panda/src/audiotraits/fmodAudioDSP.h | 148 +++---- panda/src/audiotraits/fmodAudioManager.cxx | 61 ++- panda/src/audiotraits/fmodAudioManager.h | 16 +- panda/src/audiotraits/fmodAudioSound.cxx | 428 ++++++++------------- panda/src/audiotraits/fmodAudioSound.h | 7 + 10 files changed, 337 insertions(+), 462 deletions(-) diff --git a/doc/SceneEditor/collisionWindow.py b/doc/SceneEditor/collisionWindow.py index 55559c1407..1832d33fcb 100644 --- a/doc/SceneEditor/collisionWindow.py +++ b/doc/SceneEditor/collisionWindow.py @@ -11,6 +11,7 @@ from direct.tkwidgets import Floater from direct.tkwidgets import Slider from Tkinter import * import string, math, types +from pandac.PandaModules import * class collisionWindow(AppShell): diff --git a/doc/SceneEditor/lightingPanel.py b/doc/SceneEditor/lightingPanel.py index f40bb4f972..f422215c0d 100644 --- a/doc/SceneEditor/lightingPanel.py +++ b/doc/SceneEditor/lightingPanel.py @@ -9,7 +9,7 @@ from direct.tkwidgets.VectorWidgets import Vector3Entry from direct.tkwidgets.Slider import Slider from Tkinter import Frame, Button, Menubutton, Menu import string, math, types, Pmw, Tkinter - +from pandac.PandaModules import * class lightingPanel(AppShell): ################################################################# diff --git a/doc/SceneEditor/seMopathRecorder.py b/doc/SceneEditor/seMopathRecorder.py index c74c229dea..9346e44590 100644 --- a/doc/SceneEditor/seMopathRecorder.py +++ b/doc/SceneEditor/seMopathRecorder.py @@ -18,6 +18,7 @@ from direct.tkwidgets.AppShell import AppShell #from direct.directtools.DirectUtil import * from seGeometry import * from seSelection import * +from direct.task.Task import Task from direct.tkwidgets.Dial import AngleDial from direct.tkwidgets.Floater import Floater from direct.tkwidgets.Slider import Slider diff --git a/panda/src/audio/audioManager.h b/panda/src/audio/audioManager.h index 86c97d6159..85132b5a72 100644 --- a/panda/src/audio/audioManager.h +++ b/panda/src/audio/audioManager.h @@ -31,59 +31,58 @@ class EXPCL_PANDA AudioManager : public TypedReferenceCount { PUBLISHED: - //This is an enumerator for the FMOD DSPs. - //The reason why this is here, is because Panda's DTOOL interegator - //For the Python Bindings, does not seem to like getting 'PUBLISHED' - //Functions in the AudioTraits. - //I guess this is a bug, but it was beyond me. - enum DSP_category { - // These enumerants line up one-to-one - // with the FMOD DSP enumerants. - DSP_unknown, - DSP_mixer, - DSP_oscillator, - DSP_lowpass, - DSP_itlowpass, - DSP_highpass, - DSP_echo, - DSP_flange, - DSP_distortion, - DSP_normalize, - DSP_parameq, - DSP_pitchshift, - DSP_chorus, - DSP_reverb, - DSP_vstplugin, - DSP_winampplugin, - DSP_itecho, - DSP_compressor, - DSP_COUNT - }; - - enum SPEAKERMODE_category{ - // These enumerants line up one-to-one - // with the FMOD SPEAKERMODE enumerants. - SPEAKERMODE_raw, - SPEAKERMODE_mono, - SPEAKERMODE_stereo, - SPEAKERMODE_quad, - SPEAKERMODE_surround, - SPEAKERMODE_5point1, - SPEAKERMODE_7point1, - SPEAKERMODE_prologic, - SPEAKERMODE_max, - SPEAKERMODE_COUNT - }; - - virtual PT(AudioDSP) create_dsp(DSP_category cat); - - virtual bool add_dsp(PT(AudioDSP) x); - virtual bool remove_dsp(PT(AudioDSP) x); - - - virtual int getSpeakerSetup(); - virtual void setSpeakerSetup(SPEAKERMODE_category cat); - + //This is an enumerator for the FMOD DSPs. + //The reason why this is here, is because Panda's DTOOL interegator + //For the Python Bindings, does not seem to like getting 'PUBLISHED' + //Functions in the AudioTraits. + //I guess this is a bug, but it was beyond me. + enum DSP_category { + // These enumerants line up one-to-one + // with the FMOD DSP enumerants. + DSP_unknown, + DSP_mixer, + DSP_oscillator, + DSP_lowpass, + DSP_itlowpass, + DSP_highpass, + DSP_echo, + DSP_flange, + DSP_distortion, + DSP_normalize, + DSP_parameq, + DSP_pitchshift, + DSP_chorus, + DSP_reverb, + DSP_vstplugin, + DSP_winampplugin, + DSP_itecho, + DSP_compressor, + DSP_COUNT + }; + + enum SPEAKERMODE_category{ + // These enumerants line up one-to-one + // with the FMOD SPEAKERMODE enumerants. + SPEAKERMODE_raw, + SPEAKERMODE_mono, + SPEAKERMODE_stereo, + SPEAKERMODE_quad, + SPEAKERMODE_surround, + SPEAKERMODE_5point1, + SPEAKERMODE_7point1, + SPEAKERMODE_prologic, + SPEAKERMODE_max, + SPEAKERMODE_COUNT + }; + + virtual PT(AudioDSP) create_dsp(DSP_category cat); + + virtual bool add_dsp(PT(AudioDSP) x); + virtual bool remove_dsp(PT(AudioDSP) x); + + virtual int getSpeakerSetup(); + virtual void setSpeakerSetup(SPEAKERMODE_category cat); + // Create an AudioManager for each category of sounds you have. // E.g. // MySoundEffects = create_AudioManager::AudioManager(); diff --git a/panda/src/audiotraits/fmodAudioDSP.cxx b/panda/src/audiotraits/fmodAudioDSP.cxx index d20d57d93d..dee21ef7fb 100644 --- a/panda/src/audiotraits/fmodAudioDSP.cxx +++ b/panda/src/audiotraits/fmodAudioDSP.cxx @@ -51,7 +51,7 @@ FmodAudioDSP(AudioManager *manager, AudioManager::DSP_category cat) { FMOD_DSP_TYPE dsptype = (FMOD_DSP_TYPE)cat; result = _manager->_system->createDSPByType( dsptype, &_dsp); - ERRCHECK(result); + fmod_audio_errcheck(result); set_in_chain(false); @@ -74,10 +74,10 @@ FmodAudioDSP:: FMOD_RESULT result; result = _dsp->remove(); - ERRCHECK(result); + fmod_audio_errcheck(result); result = _dsp->release(); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("DSP GONE"); } @@ -98,7 +98,7 @@ reset() { FMOD_RESULT result; result = _dsp->reset(); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("DSP Reset."); } @@ -118,7 +118,7 @@ remove() { FMOD_RESULT result; result = _dsp->remove(); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("DSP Removed from relative effects chain."); } @@ -138,7 +138,7 @@ set_bypass(bool bypass) { FMOD_RESULT result; result = _dsp->setBypass(bypass); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("DSP Bypass set to:" << bypass ); } @@ -159,7 +159,7 @@ get_bypass() { bool bypass; result = _dsp->getBypass(&bypass); - ERRCHECK(result); + fmod_audio_errcheck(result); return bypass; } @@ -183,7 +183,7 @@ set_parameter(const string &name, float value) { FMOD_RESULT result; result = _dsp->setParameter(parameterIndex, value); - ERRCHECK(result); + fmod_audio_errcheck(result); } @@ -203,7 +203,7 @@ get_num_parameters() { int numOfParameters; result = _dsp->getNumParameters(&numOfParameters); - ERRCHECK(result); + fmod_audio_errcheck(result); return numOfParameters; } @@ -231,7 +231,7 @@ get_parameter_name(int parameterIndex) { float parameterMax; result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, ¶meterMin, ¶meterMax); - ERRCHECK(result); + fmod_audio_errcheck(result); string returnInfo = (parameterName); @@ -275,7 +275,7 @@ get_parameter_description(int parameterIndex) { float parameterMax; result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, ¶meterMin, ¶meterMax); - ERRCHECK(result); + fmod_audio_errcheck(result); return parameterLabel; @@ -304,7 +304,7 @@ get_parameter_min(int parameterIndex) { float parameterMax; result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, ¶meterMin, ¶meterMax); - ERRCHECK(result); + fmod_audio_errcheck(result); return parameterMin; } @@ -332,7 +332,7 @@ get_parameter_max(int parameterIndex) { float parameterMax; result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, ¶meterMin, ¶meterMax); - ERRCHECK(result); + fmod_audio_errcheck(result); return parameterMax; } @@ -361,7 +361,7 @@ get_parameter_value(const string &name) { result = _dsp->getParameter(parameterIndex, ¶meterValue, valuestr, valuestrlen); - ERRCHECK(result); + fmod_audio_errcheck(result); return parameterValue; } @@ -404,7 +404,7 @@ get_dsp_name() { int configheight; result = _dsp->getInfo(name, &version, &channels, &configwidth, &configheight); - ERRCHECK(result); + fmod_audio_errcheck(result); string returnInfo = (name); //returnInfo.append(" Version: "); diff --git a/panda/src/audiotraits/fmodAudioDSP.h b/panda/src/audiotraits/fmodAudioDSP.h index db090ed39f..d9418d218e 100644 --- a/panda/src/audiotraits/fmodAudioDSP.h +++ b/panda/src/audiotraits/fmodAudioDSP.h @@ -27,37 +27,37 @@ // //Currently FmodAudioDSP give you access to all of FMOD’s built in DSP functions. // -//The enumerated list for the types are found in the ‘AudioManager.h’, but I will +//The enumerated list for the types are found in the 'AudioManager.h’, but I will //repeat it here for good fortune. // -// enum DSP_category { -// // These enumerants line up one-to-one -// // with the FMOD DSP enumerants. -// DSP_unknown, -// DSP_mixer, -// DSP_oscillator, -// DSP_lowpass, -// DSP_itlowpass, -// DSP_highpass, -// DSP_echo, -// DSP_flange, -// DSP_distortion, -// DSP_normalize, -// DSP_parameq, -// DSP_pitchshift, -// DSP_chorus, -// DSP_reverb, -// DSP_vstplugin, -// DSP_winampplugin, -// DSP_itecho, -// DSP_COUNT -// }; +// enum DSP_category { +// // These enumerants line up one-to-one +// // with the FMOD DSP enumerants. +// DSP_unknown, +// DSP_mixer, +// DSP_oscillator, +// DSP_lowpass, +// DSP_itlowpass, +// DSP_highpass, +// DSP_echo, +// DSP_flange, +// DSP_distortion, +// DSP_normalize, +// DSP_parameq, +// DSP_pitchshift, +// DSP_chorus, +// DSP_reverb, +// DSP_vstplugin, +// DSP_winampplugin, +// DSP_itecho, +// DSP_COUNT +// }; // //Now, I want to point a couple things out. First, we have to place the above list -//in AudioManager.h because that was the only way to them to be ‘PUBLISHED’ in +//in AudioManager.h because that was the only way to them to be 'PUBLISHED’ in //Panda’s Python bindings when you build Panda. // -//Second, you only need to use the ‘it####’ named DSP effects if you are using +//Second, you only need to use the 'it####’ named DSP effects if you are using //mod/tracker files. [If you don’t know what a mod/tracker file is you probably //aren’t using them so don’t worry about it.] // @@ -82,70 +82,70 @@ class EXPCL_FMOD_AUDIO FmodAudioDSP : public AudioDSP { - public: + public: - FmodAudioDSP(AudioManager *mgr, AudioManager::DSP_category); + FmodAudioDSP(AudioManager *mgr, AudioManager::DSP_category); - virtual void reset(); - virtual void remove(); - virtual void set_bypass(bool bypass); - virtual void set_parameter(const string &name, float value); - virtual float get_parameter_value(const string &name); + virtual void reset(); + virtual void remove(); + virtual void set_bypass(bool bypass); + virtual void set_parameter(const string &name, float value); + virtual float get_parameter_value(const string &name); - virtual bool get_bypass(); + virtual bool get_bypass(); - virtual int get_num_parameters(); - virtual string get_parameter_name(int index); - virtual string get_parameter_description(int index); - virtual float get_parameter_min(int index); - virtual float get_parameter_max(int index); + virtual int get_num_parameters(); + virtual string get_parameter_name(int index); + virtual string get_parameter_description(int index); + virtual float get_parameter_min(int index); + virtual float get_parameter_max(int index); - bool get_in_chain(); - void set_in_chain(bool chain_state); + bool get_in_chain(); + void set_in_chain(bool chain_state); - virtual ~FmodAudioDSP(); + virtual ~FmodAudioDSP(); - protected: - virtual string get_dsp_name(); - + protected: + virtual string get_dsp_name(); + - private: - int find_parameter(const string &pn); + private: + int find_parameter(const string &pn); - bool _in_chain; - FmodAudioManager *_manager; - FMOD::DSP *_dsp; + bool _in_chain; + FmodAudioManager *_manager; + FMOD::DSP *_dsp; - friend class FmodAudioManager; - friend class FmodAudioSound; + friend class FmodAudioManager; + friend class FmodAudioSound; - //////////////////////////////////////////////////////////// - //These are needed for Panda's Pointer System. DO NOT ERASE! - //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + //These are needed for Panda's Pointer System. DO NOT ERASE! + //////////////////////////////////////////////////////////// - public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type() { - AudioDSP::init_type(); - register_type(_type_handle, "FmodAudioDSP", AudioDSP::get_class_type()); - } - virtual TypeHandle get_type() const { - return get_class_type(); - } - virtual TypeHandle force_init_type() { - init_type(); - return get_class_type(); - } + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + AudioDSP::init_type(); + register_type(_type_handle, "FmodAudioDSP", AudioDSP::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() { + init_type(); + return get_class_type(); + } - private: - static TypeHandle _type_handle; + private: + static TypeHandle _type_handle; - //////////////////////////////////////////////////////////// - //DONE - //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + //DONE + //////////////////////////////////////////////////////////// }; diff --git a/panda/src/audiotraits/fmodAudioManager.cxx b/panda/src/audiotraits/fmodAudioManager.cxx index 30b2dc8e3b..261eba2d83 100644 --- a/panda/src/audiotraits/fmodAudioManager.cxx +++ b/panda/src/audiotraits/fmodAudioManager.cxx @@ -39,32 +39,25 @@ #include -//////////////////////////////////////////////////////////////////// -// This in needed for Panda's Pointer System -// DO NOT ERASE! -//////////////////////////////////////////////////////////////////// TypeHandle FmodAudioManager::_type_handle; -//////////////////////////////////////////////////////////////////// -// END OF POINTER THING -//////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////// -// OK I am not sure if there is the best place for this one, -// but it seems to work. IE, the FmodSound and FmodDSP classes can find it. -// All FMOD API calls return a success or failure error. -// [I am sure there is a name for this type of programming but I don't know it.] -// Anyway, by adding the line "notify-level-audio debug" to the config.prc file -// of Panda, of the config.in file of MAKEPANDA, you can see the Debugs printed out at the -// Python Prompt -///////////////////////////////////////////////////////////////////// -void ERRCHECK(FMOD_RESULT result){ - audio_debug("FMOD State: "<< result <<" "<< FMOD_ErrorString(result) ); +// Central dispatcher for audio errors. +//////////////////////////////////////////////////////////////////// + +static void fmod_audio_errcheck(FMOD_RESULT result) { + if (result != 0) { + audio_error("FMOD State: "<< result <<" "<< FMOD_ErrorString(result) ); + } } - +//////////////////////////////////////////////////////////////////// +// Function: Create_AudioManager +// Access: Private +// Description: Factory Function +//////////////////////////////////////////////////////////////////// PT(AudioManager) Create_AudioManager() { audio_debug("Create_AudioManager() Fmod."); return new FmodAudioManager; @@ -108,12 +101,12 @@ FmodAudioManager() { audio_debug("FMOD::System_Create()"); result = FMOD::System_Create(&_system); - ERRCHECK(result); + fmod_audio_errcheck(result); // Let check the Version of FMOD to make sure the Headers and Libraries are correct. audio_debug("FMOD::System_Create()"); result = _system->getVersion(&version); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("FMOD VERSION:" << hex << version ); audio_debug("FMOD - Getting Version"); @@ -129,14 +122,14 @@ FmodAudioManager() { if (fmod_use_surround_sound) { audio_debug("Setting FMOD to use 5.1 Surround Sound."); result = _system->setSpeakerMode( FMOD_SPEAKERMODE_5POINT1 ); - ERRCHECK(result); + fmod_audio_errcheck(result); } //Now we Initialize the System. audio_debug("FMOD::System_Init"); result = _system->init(fmod_number_of_sound_channels, FMOD_INIT_NORMAL, 0); - ERRCHECK(result); + fmod_audio_errcheck(result); if (result == FMOD_OK){ audio_debug("FMOD Intialized OK, We are good to go Houston!"); @@ -160,7 +153,7 @@ FmodAudioManager() { audio_debug("Setting 3D Audio settings: Doppler Factor, Distance Factor, Drop Off Factor"); result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } @@ -183,10 +176,10 @@ FmodAudioManager:: _all_sounds.clear(); //result = _system->close(); - //ERRCHECK(result); + //fmod_audio_errcheck(result); result = _system->release(); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("~FmodAudioManager(): System Down."); @@ -275,7 +268,7 @@ add_dsp( PT(AudioDSP) x) { { result = _system->addDSP( fdsp->_dsp ); - ERRCHECK( result ); + fmod_audio_errcheck( result ); _system_dsp.insert(fdsp); @@ -305,7 +298,7 @@ remove_dsp(PT(AudioDSP) x) { if ( fdsp->get_in_chain() ) { result = fdsp->_dsp->remove(); - ERRCHECK( result ); + fmod_audio_errcheck( result ); _system_dsp.erase(fdsp); @@ -340,7 +333,7 @@ getSpeakerSetup() { int returnMode; result = _system->getSpeakerMode( &speakerMode ); - ERRCHECK( result ); + fmod_audio_errcheck( result ); switch (speakerMode) { case FMOD_SPEAKERMODE_RAW: @@ -409,7 +402,7 @@ setSpeakerSetup(AudioManager::SPEAKERMODE_category cat) { FMOD_SPEAKERMODE speakerModeType = (FMOD_SPEAKERMODE)cat; result = _system->setSpeakerMode( speakerModeType); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("Speaker Mode Set"); @@ -531,7 +524,7 @@ audio_3d_set_listener_attributes(float px, float py, float pz, float vx, float v _up.z = uy; result = _system->set3DListenerAttributes( 0, &_position, &_velocity, &_forward, &_up); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } @@ -562,7 +555,7 @@ audio_3d_set_distance_factor(float factor) { _distance_factor = factor; result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } @@ -595,7 +588,7 @@ audio_3d_set_doppler_factor(float factor) { _doppler_factor = factor; result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } @@ -626,7 +619,7 @@ audio_3d_set_drop_off_factor(float factor) { _drop_off_factor = factor; result = _system->set3DSettings( _doppler_factor, _distance_factor, _drop_off_factor); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } diff --git a/panda/src/audiotraits/fmodAudioManager.h b/panda/src/audiotraits/fmodAudioManager.h index 3dd276e775..0a5f287301 100644 --- a/panda/src/audiotraits/fmodAudioManager.h +++ b/panda/src/audiotraits/fmodAudioManager.h @@ -82,22 +82,9 @@ class FmodAudioSound; class FmodAudioDSP; -//////////////////////////////////////////////////////////////////// -// OK I am not sure if there is the best place for this one, -// but it seems to work. IE, the FmodSound and FmodDSP classes can find it. -// All FMOD API calls return a success or failure error. -// [I am sure there is a name for this type of programming but I don't know it.] -// Anyway, by adding the line "notify-level-audio debug" to the config.prc file -// of Panda, of the config.in file of MAKEPANDA, you can see the Debugs printed out at the -// Python Prompt -///////////////////////////////////////////////////////////////////// -void ERRCHECK(FMOD_RESULT result); - +extern void fmod_audio_errcheck(FMOD_RESULT n); class EXPCL_FMOD_AUDIO FmodAudioManager : public AudioManager { - // All of these methods are stubbed out to some degree. - // If you're looking for a starting place for a new AudioManager, - // please consider looking at the milesAudioManager. friend class FmodAudioSound; friend class FmodAudioDSP; @@ -251,6 +238,7 @@ class EXPCL_FMOD_AUDIO FmodAudioManager : public AudioManager { EXPCL_FMOD_AUDIO PT(AudioManager) Create_AudioManager(); + #endif //] #endif /* __FMOD_AUDIO_MANAGER_H__ */ diff --git a/panda/src/audiotraits/fmodAudioSound.cxx b/panda/src/audiotraits/fmodAudioSound.cxx index a57e06ad16..b0ae33cb68 100644 --- a/panda/src/audiotraits/fmodAudioSound.cxx +++ b/panda/src/audiotraits/fmodAudioSound.cxx @@ -32,13 +32,12 @@ TypeHandle FmodAudioSound::_type_handle; - //////////////////////////////////////////////////////////////////// // Function: FmodAudioSound::FmodAudioSound // Access: public -// Description: CONSTRUCTOR +// Description: Constructor // All sound will DEFAULT load as a 2D sound unless -// otherwise specified. +// otherwise specified. //////////////////////////////////////////////////////////////////// FmodAudioSound:: @@ -75,17 +74,17 @@ FmodAudioSound(AudioManager *manager, string file_name, bool positional) { DCAST_INTO_V(fmanager, manager); _manager = fmanager; - //_channel = 0; + _channel = 0; _file_name = file_name; //Get the Speaker Mode [Important for later on.] result = _manager->_system->getSpeakerMode( &_speakermode ); - ERRCHECK(result); + fmod_audio_errcheck(result); if (positional == true) { result = _manager->_system->createSound( file_name.c_str(), FMOD_SOFTWARE | FMOD_3D , 0, &_sound); - ERRCHECK(result); + fmod_audio_errcheck(result); //This is just to collect the defaults of the sound, so we don't //Have to query FMOD everytime for the info. @@ -93,14 +92,14 @@ FmodAudioSound(AudioManager *manager, string file_name, bool positional) { //'set_play_rate()' and 'get_play_rate()' methods later; result = _sound->getDefaults( &_sampleFrequency, &_volume , &_balance, &_priority); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("Sound loaded as 3D"); } else { result = _manager->_system->createSound( file_name.c_str(), FMOD_SOFTWARE | FMOD_2D , 0, &_sound); - ERRCHECK(result); + fmod_audio_errcheck(result); //This is just to collect the defaults of the sound, so we don't //Have to query FMOD everytime for the info. @@ -108,7 +107,7 @@ FmodAudioSound(AudioManager *manager, string file_name, bool positional) { //'set_play_rate()' and 'get_play_rate()' methods later; result = _sound->getDefaults( &_sampleFrequency, &_volume , &_balance, &_priority); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("Sound loaded as 2D"); @@ -136,7 +135,7 @@ FmodAudioSound:: //The Release Sound result = _sound->release(); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("FmodAudioSound::~FmodAudioSound() FMOD Sound Released and Closed."); @@ -190,53 +189,47 @@ FmodAudioSound:: //////////////////////////////////////////////////////////////////// void FmodAudioSound:: play() { - - audio_debug("FmodAudioSound::play() Going to play a sound." ); - FMOD_RESULT result; - bool paused = 0; - - result = _channel->getPaused(&paused); - ERRCHECK(result); - - - if ( paused ) { - - set_volume_on_channel(); - set_play_rate_on_channel(); - set_speaker_mix_or_balance_on_channel(); - add_dsp_on_channel(); - - result = _channel->setPaused(false); - ERRCHECK(result); - - } else { - - prepareSound(); - - set_volume_on_channel(); - set_play_rate_on_channel(); - set_speaker_mix_or_balance_on_channel();; - add_dsp_on_channel(); - - result = _channel->setPaused(false); - ERRCHECK(result); - - } - - audio_debug("FmodAudioSound::play() Sound should be playing (or played if it is really short)." ); + set_time(0.0); + result = _channel->setPaused(false); + fmod_audio_errcheck(result); +} + +//////////////////////////////////////////////////////////////////// +// Function: sound_end_callback +// Access: Static +// Description: When fmod finishes playing a sound, the channel +// handle of the sound becomes invalid. This callback +// removes the invalid channel handle from the relevant +// fmodAudioSound. +//////////////////////////////////////////////////////////////////// +static FMOD_RESULT F_CALLBACK sound_end_callback(FMOD_CHANNEL * channel, + FMOD_CHANNEL_CALLBACKTYPE type, + int command, + unsigned int commanddata1, + unsigned int commanddata2) { + FmodAudioSound *fsound = (FmodAudioSound*)command; + if (fsound->_channel != 0) { + fsound->_channel = 0; + fsound->unref(); + } + return FMOD_OK; } - //////////////////////////////////////////////////////////////////// // Function: FmodAudioSound::prepareSound // Access: Private // Description: Prepares a sound [GENERAL] //////////////////////////////////////////////////////////////////// + void FmodAudioSound:: prepareSound() { + if (_channel != 0) { + return; + } + audio_debug("FmodAudioSound::prepareSound()" ); FMOD_RESULT result; @@ -246,18 +239,23 @@ prepareSound() { audio_debug("FmodAudioSound::play() Going to perpare a sound." ); result = _sound->getMode(&soundMode); - ERRCHECK(result); - - if ( ( soundMode & FMOD_3D ) > 0 ) { + fmod_audio_errcheck(result); + if ( soundMode & FMOD_3D ) { prepare3DSound(); - } else { - prepare2DSound(); - } + // This function sets up an fmod callback, which will + // clear the _channel variable when the sound stops playing. + // We want to make sure this fmodAudioSound doesn't go away + // until after the _channel is cleared, so I increment the + // ref-count. + this->ref(); + + result = _channel->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, sound_end_callback, (int)this); + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -280,7 +278,7 @@ prepare2DSound() { FMOD_RESULT result; result = _manager->_system->playSound(FMOD_CHANNEL_REUSE, _sound, true, &_channel); - ERRCHECK(result); + fmod_audio_errcheck(result); } @@ -304,10 +302,10 @@ prepare3DSound() { FMOD_RESULT result; result = _manager->_system->playSound(FMOD_CHANNEL_REUSE, _sound, true, &_channel); - ERRCHECK(result); + fmod_audio_errcheck(result); result = _channel->set3DAttributes( &_location, &_velocity ); - ERRCHECK(result); + fmod_audio_errcheck(result); } @@ -325,9 +323,13 @@ stop() { //LOCALS FMOD_RESULT result; - result = _channel->stop(); - ERRCHECK(result); - + if (_channel != 0) { + result = _channel->stop(); + fmod_audio_errcheck(result); + _channel = 0; + unref(); + } + audio_debug("FmodAudioSound::stop() Sound should be stopped."); } @@ -344,12 +346,12 @@ set_loop(bool loop) { FMOD_RESULT result; if ( loop ) { result = _sound->setMode(FMOD_LOOP_NORMAL); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("This sound is set to loop." ); } else { result = _sound->setMode(FMOD_LOOP_OFF); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("FmodAudioSound::set_loop() This sound is set to one-shot." ); } } @@ -373,7 +375,7 @@ get_loop() const { bool loopState; result = _sound->getMode( &loopMode ); - ERRCHECK(result); + fmod_audio_errcheck(result); if ( (loopMode & FMOD_LOOP_NORMAL) != 0 ) { loopState = true; @@ -407,10 +409,10 @@ set_loop_count(unsigned long loop_count) { if (numberOfLoops == 0) { result = _sound->setLoopCount( -1 ); - ERRCHECK(result); + fmod_audio_errcheck(result); } else { result = _sound->setLoopCount( numberOfLoops ); - ERRCHECK(result); + fmod_audio_errcheck(result); } audio_debug("FmodAudioSound::set_loop_count() Sound's loop count should be set to: " << loop_count); @@ -431,7 +433,7 @@ get_loop_count() const { unsigned long returnedNumber; result = _sound->getLoopCount( &loop_count ); - ERRCHECK(result); + fmod_audio_errcheck(result); audio_debug("FmodAudioSound::get_loop_count() returning "<< loop_count); @@ -451,17 +453,18 @@ set_time(float start_time) { FMOD_RESULT result; audio_debug("FmodAudioSound::set_time() Going to set a sounds start position" ); - unsigned int startTime; - - //We must 'prepareSound()' [set it to play on a channel] so - //we can set its start time. prepareSound(); - startTime = start_time * 1000; + set_volume_on_channel(); + set_play_rate_on_channel(); + set_speaker_mix_or_balance_on_channel(); + add_dsp_on_channel(); + set_3d_attributes_on_channel(); + + int startTime = start_time * 1000; result = _channel->setPosition( startTime , FMOD_TIMEUNIT_MS ); - ERRCHECK(result); - + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -473,11 +476,15 @@ float FmodAudioSound:: get_time() const { audio_debug("FmodAudioSound::get_time() Going to get a sound's position" ); + if (_channel == 0) { + return 0.0f; + } + FMOD_RESULT result; unsigned int current_time; result = _channel->getPosition( ¤t_time , FMOD_TIMEUNIT_MS ); - ERRCHECK(result); + fmod_audio_errcheck(result); current_time = current_time / 1000; @@ -492,17 +499,8 @@ get_time() const { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_volume(float vol) { - - audio_debug("FmodAudioSound::set_volume() Going to set a sounds volume." ); - - FMOD_RESULT result; - _volume = vol; - - result = _channel->setVolume( _volume ); - ERRCHECK(result); - - audio_debug("FmodAudioSound::set_volume() Setting volume to " << vol); + set_volume_on_channel(); } //////////////////////////////////////////////////////////////////// @@ -512,14 +510,14 @@ set_volume(float vol) { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_volume_on_channel() { - audio_debug("FmodAudioSound::set_volume() Going to set a sounds volume." ); - FMOD_RESULT result; - result = _channel->setVolume( _volume ); - ERRCHECK(result); + if (_channel == 0) { + return; + } - audio_debug("FmodAudioSound::set_volume() Setting volume to " << _volume ); + result = _channel->setVolume( _volume ); + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -529,9 +527,6 @@ set_volume_on_channel() { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: get_volume() const { - - audio_debug("FmodAudioSound::get_volume() Going to get a sound's volume." ); - return _volume; } @@ -542,39 +537,8 @@ get_volume() const { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_balance(float bal) { - audio_debug("FmodAudioSound::set_balance() Going to set a sound's balance." ); - - FMOD_RESULT result; - _balance = bal; - - result = _sound->setDefaults( _sampleFrequency, _volume , _balance, _priority); - ERRCHECK(result); - - result = _channel->setPan( _balance ); - ERRCHECK(result); - - audio_debug("FmodAudioSound::set_balance() Setting Pan to " << bal); -} - -//////////////////////////////////////////////////////////////////// -// Function: FmodAudioSound::set_balance_on_channel() -// Access: public -// Description: -1.0 to 1.0 scale Set the pan on a prepared Sound channel. -// -1 should be all the way left. -// 1 is all the way to the right. -//////////////////////////////////////////////////////////////////// -void FmodAudioSound:: -set_balance_on_channel() { - - audio_debug("FmodAudioSound::set_balance() Going to set a sound's balance to " << _balance ); - - FMOD_RESULT result; - - result = _channel->setPan( _balance ); - ERRCHECK(result); - - audio_debug("FmodAudioSound::set_balance() Setting Pan to " << _balance); + set_speaker_mix_or_balance_on_channel(); } //////////////////////////////////////////////////////////////////// @@ -586,9 +550,6 @@ set_balance_on_channel() { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: get_balance() const { - - audio_debug("FmodAudioSound::get_balance() Going to get a sound's balance." ); - return _balance; } @@ -604,25 +565,8 @@ get_balance() const { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_play_rate(float rate) { - audio_debug("FmodAudioSound::set_play_rate() Going to set a sound's play rate to " << rate); - - FMOD_RESULT result; - float frequencyToSetChannelTo; - _playrate = rate; - - if (rate == 1) { - result = _channel->setFrequency( _sampleFrequency ); - ERRCHECK(result); - } else { - frequencyToSetChannelTo = _sampleFrequency * rate ; - - result = _channel->setFrequency( frequencyToSetChannelTo ); - ERRCHECK(result); - - } - - audio_debug("FmodAudioSound::set_play_rate() Sound's balance set to " << rate); + set_play_rate_on_channel(); } //////////////////////////////////////////////////////////////////// @@ -632,28 +576,23 @@ set_play_rate(float rate) { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_play_rate_on_channel() { - audio_debug("FmodAudioSound::set_play_rate() Going to set a sound's balance to " << _playrate); - FMOD_RESULT result; - float frequencyToSetChannelTo; + + if (_channel == 0) { + return; + } + float frequencyToSetChannelTo; if ( _playrate == 1) { result = _channel->setFrequency( _sampleFrequency ); - ERRCHECK(result); + fmod_audio_errcheck(result); } else { frequencyToSetChannelTo = _sampleFrequency * _playrate ; - result = _channel->setFrequency( frequencyToSetChannelTo ); - ERRCHECK(result); - + fmod_audio_errcheck(result); } - - audio_debug("FmodAudioSound::set_play_rate() Sound's balance set to " << _playrate); - } - - //////////////////////////////////////////////////////////////////// // Function: FmodAudioSound::get_play_rate // Access: public @@ -661,13 +600,9 @@ set_play_rate_on_channel() { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: get_play_rate() const { - - audio_debug("FmodAudioSound::set_play_rate() Going to get a sound's balance."); - return _playrate; } - //////////////////////////////////////////////////////////////////// // Function: FmodAudioSound::get_name // Access: public @@ -675,8 +610,6 @@ get_play_rate() const { //////////////////////////////////////////////////////////////////// const string& FmodAudioSound:: get_name() const { - audio_debug("FmodAudioSound::get_name() Going to get a sound's file name."); - return _file_name; } @@ -688,14 +621,11 @@ get_name() const { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: length() const { - - audio_debug("FmodAudioSound::length() Going to get a sound's length in second."); - FMOD_RESULT result; unsigned int length; result = _sound->getLength( &length, FMOD_TIMEUNIT_MS ); - ERRCHECK(result); + fmod_audio_errcheck(result); length = length / 1000; @@ -719,10 +649,6 @@ length() const { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) { - audio_debug("FmodAudioSound::set_3d_attributes() Setting a sound's 3D Coordinates."); - - FMOD_RESULT result; - _location.x = px; _location.y = pz; _location.z = py; @@ -730,9 +656,31 @@ set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) { _velocity.x = vx; _velocity.y = vz; _velocity.z = vy; + + set_3d_attributes_on_channel(); +} + +//////////////////////////////////////////////////////////////////// +// Function: FmodAudioSound::set_3d_attributes +// Access: public +// Description: +//////////////////////////////////////////////////////////////////// +void FmodAudioSound:: +set_3d_attributes_on_channel() { + FMOD_RESULT result; + FMOD_MODE soundMode; + + if (_channel == 0) { + return; + } - result = _channel->set3DAttributes( &_location, &_velocity ); - ERRCHECK(result); + result = _sound->getMode(&soundMode); + fmod_audio_errcheck(result); + + if ( soundMode & FMOD_3D ) { + result = _channel->set3DAttributes( &_location, &_velocity ); + fmod_audio_errcheck(result); + } } //////////////////////////////////////////////////////////////////// @@ -744,7 +692,6 @@ set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) { void FmodAudioSound:: get_3d_attributes(float *px, float *py, float *pz, float *vx, float *vy, float *vz) { audio_error("get3dAttributes: Currently unimplemented. Get the attributes of the attached object."); - } //////////////////////////////////////////////////////////////////// @@ -755,17 +702,12 @@ get_3d_attributes(float *px, float *py, float *pz, float *vx, float *vy, float * //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_3d_min_distance(float dist) { - - audio_debug("FmodAudioSound::set_3d_min_distance() Setting the sound's 3D min distance ( min= " << dist << " ) "); - FMOD_RESULT result; _min_dist = dist; result = _sound->set3DMinMaxDistance( dist, _max_dist ); - ERRCHECK(result); - - + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -775,9 +717,6 @@ set_3d_min_distance(float dist) { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: get_3d_min_distance() const { - - audio_debug("FmodAudioSound::get_3d_min_distance() "); - return _min_dist; } @@ -788,16 +727,12 @@ get_3d_min_distance() const { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_3d_max_distance(float dist) { - - audio_debug("FmodAudioSound::set_3d_max_distance() Setting the sound's 3D max distance ( max= " << dist << " ) "); - FMOD_RESULT result; _max_dist = dist; result = _sound->set3DMinMaxDistance( _min_dist, dist ); - ERRCHECK(result); - + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -807,9 +742,6 @@ set_3d_max_distance(float dist) { //////////////////////////////////////////////////////////////////// float FmodAudioSound:: get_3d_max_distance() const { - - audio_debug("FmodAudioSound::get_3d_max_distance() "); - return _max_dist; } @@ -825,8 +757,6 @@ get_3d_max_distance() const { //////////////////////////////////////////////////////////////////// bool FmodAudioSound:: add_dsp( PT(AudioDSP) x) { - audio_debug("FmodAudioManager()::add_dsp"); - FMOD_RESULT result; bool playingState; @@ -839,26 +769,24 @@ add_dsp( PT(AudioDSP) x) { return false; - } else - { - - _sound_dsp.insert(fdsp); - - if ( _channel != 0 ) { - result = _channel->isPlaying( &playingState ); - ERRCHECK(result); - if ( playingState ) { - result = _channel->addDSP( fdsp->_dsp ); - ERRCHECK( result ); - } + } else { + + _sound_dsp.insert(fdsp); + + if ( _channel != 0 ) { + result = _channel->isPlaying( &playingState ); + fmod_audio_errcheck(result); + if ( playingState ) { + result = _channel->addDSP( fdsp->_dsp ); + fmod_audio_errcheck( result ); } - - fdsp->set_in_chain(true); - - return true; - } - + + fdsp->set_in_chain(true); + + return true; + + } } //////////////////////////////////////////////////////////////////// @@ -875,7 +803,7 @@ add_dsp_on_channel() { for (DSPSet::iterator i = _sound_dsp.begin(); i != _sound_dsp.end(); ++i) { result = _channel->addDSP( (*i)->_dsp ); - ERRCHECK( result ); + fmod_audio_errcheck( result ); } } @@ -902,7 +830,7 @@ remove_dsp(PT(AudioDSP) x) { if ( fdsp->get_in_chain() ) { result = fdsp->_dsp->remove(); - ERRCHECK( result ); + fmod_audio_errcheck( result ); _sound_dsp.erase(fdsp); @@ -949,6 +877,10 @@ get_speaker_mix(int speaker) { audio_debug("FmodAudioSound::getSpeakerMix()"); + if (_channel == 0) { + return 0.0; + } + FMOD_RESULT result; float frontleft; float frontright; @@ -961,50 +893,37 @@ get_speaker_mix(int speaker) { float returnValue; + result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); + fmod_audio_errcheck(result); + switch(speaker) { case 1: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = frontleft; break; case 2: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = frontright; break; case 3: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = center; break; case 4: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = sub; break; case 5: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = backleft; break; case 6: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = backright; break; case 7: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = sideleft; break; case 8: - result = _channel->getSpeakerMix( &frontleft, &frontright, ¢er, &sub, &backleft, &backright, &sideleft, &sideright ); - ERRCHECK(result); returnValue = sideright; break; default: - cerr << "You specified a speaker which doesn't exist."; + audio_error("You specified a speaker which doesn't exist."); } return returnValue; @@ -1027,12 +946,6 @@ get_speaker_mix(int speaker) { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_speaker_mix(float frontleft, float frontright, float center, float sub, float backleft, float backright, float sideleft, float sideright) { - // intentionally blank - - audio_debug("FmodAudioSound::setSpeakerMix()"); - - FMOD_RESULT result; - _frontleft = frontleft; _frontright = frontright; _center = center; @@ -1042,29 +955,9 @@ set_speaker_mix(float frontleft, float frontright, float center, float sub, floa _sideleft = sideleft; _sideright = sideright; - result = _channel->setSpeakerMix( _frontleft, _frontright, _center, _sub, _backleft, _backright, _sideleft, _sideright ); - ERRCHECK(result);; + set_speaker_mix_or_balance_on_channel(); } -//////////////////////////////////////////////////////////////////// -// Function: FmodAudioSound::set_speaker_mix_on_channel -// Access: Published -// Description: Set the Speaker Mix for a sound on a prepared Sound channel. -//////////////////////////////////////////////////////////////////// -void FmodAudioSound:: -set_speaker_mix_on_channel() { - // intentionally blank - - audio_debug("FmodAudioSound::setSpeakerMix()"); - - FMOD_RESULT result; - - result = _channel->setSpeakerMix( _frontleft, _frontright, _center, _sub, _backleft, _backright, _sideleft, _sideright ); - ERRCHECK(result);; -} - - - //////////////////////////////////////////////////////////////////// // Function: FmodAudioSound::set_speaker_mix_or_balance_on_channel // Access: Private @@ -1078,33 +971,26 @@ set_speaker_mix_on_channel() { //////////////////////////////////////////////////////////////////// void FmodAudioSound:: set_speaker_mix_or_balance_on_channel() { - // intentionally blank - - audio_debug("FmodAudioSound::set_speaker_mix_or_balance_on_channel()"); - FMOD_RESULT result; FMOD_MODE soundMode; - result = _sound->getMode(&soundMode); - ERRCHECK(result); - + fmod_audio_errcheck(result); if ( _speakermode == FMOD_SPEAKERMODE_STEREO ) { - //FMOD Returns an error is you try and pan a sound in 3D Audio. //Which makes sense. //It is nothing serious, but might as well avoid it while we can. - if ( !( ( soundMode & FMOD_3D ) > 0 ) ) { - set_balance_on_channel(); + if ( soundMode & FMOD_3D ) { + result = _channel->setPan( _balance ); + fmod_audio_errcheck(result); } - } else { - - set_speaker_mix_on_channel(); - + if ( soundMode & FMOD_3D ) { + result = _channel->setSpeakerMix( _frontleft, _frontright, _center, _sub, _backleft, _backright, _sideleft, _sideright ); + fmod_audio_errcheck(result); + } } - } @@ -1138,7 +1024,7 @@ set_priority(int priority) { _priority = priority; result = _sound->setDefaults( _sampleFrequency, _volume , _balance, _priority); - ERRCHECK(result); + fmod_audio_errcheck(result); } //////////////////////////////////////////////////////////////////// @@ -1158,7 +1044,7 @@ status() const { if ( _channel != 0 ) { result = _channel->isPlaying( &playingState ); - ERRCHECK(result); + fmod_audio_errcheck(result); } //audio_debug("If you get 'FMOD State: 32 An invalid object handle was used.' "); diff --git a/panda/src/audiotraits/fmodAudioSound.h b/panda/src/audiotraits/fmodAudioSound.h index c92a76921a..a6527ddb55 100644 --- a/panda/src/audiotraits/fmodAudioSound.h +++ b/panda/src/audiotraits/fmodAudioSound.h @@ -208,6 +208,7 @@ class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound { void set_balance_on_channel(); void set_play_rate_on_channel(); void set_speaker_mix_on_channel(); + void set_3d_attributes_on_channel(); void add_dsp_on_channel(); void set_speaker_mix_or_balance_on_channel(); @@ -223,6 +224,12 @@ class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound { //THESE are stubs in FMOD-EX version string _finished_event; + friend FMOD_RESULT F_CALLBACK sound_end_callback(FMOD_CHANNEL * channel, + FMOD_CHANNEL_CALLBACKTYPE type, + int command, + unsigned int commanddata1, + unsigned int commanddata2); + //////////////////////////////////////////////////////////// //These are needed for Panda's Pointer System. DO NOT ERASE! ////////////////////////////////////////////////////////////