Bläddra i källkod

Fixes to fmod and scene editor

Josh Yelon 19 år sedan
förälder
incheckning
68c918864f

+ 1 - 0
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):

+ 1 - 1
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):
     #################################################################

+ 1 - 0
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

+ 52 - 53
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();

+ 15 - 15
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, &parameterMin, &parameterMax);
-  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, &parameterMin, &parameterMax);
-  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, &parameterMin, &parameterMax);
-  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, &parameterMin, &parameterMax);
-  ERRCHECK(result);
+  fmod_audio_errcheck(result);
 
   return parameterMax;
 }
@@ -361,7 +361,7 @@ get_parameter_value(const string &name) {
 
 
   result = _dsp->getParameter(parameterIndex, &parameterValue, 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: ");

+ 74 - 74
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
+  ////////////////////////////////////////////////////////////
 
 };
 

+ 26 - 33
panda/src/audiotraits/fmodAudioManager.cxx

@@ -39,32 +39,25 @@
 #include <fmod_errors.h>
 
 
-////////////////////////////////////////////////////////////////////
-//  This in needed for Panda's Pointer System
-//  DO NOT ERASE!
-////////////////////////////////////////////////////////////////////
 
 TypeHandle FmodAudioManager::_type_handle;
 
+
 ////////////////////////////////////////////////////////////////////
-//  END OF POINTER THING
+// Central dispatcher for audio errors.
 ////////////////////////////////////////////////////////////////////
 
-
-////////////////////////////////////////////////////////////////////
-//  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) );
+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 );
 
 }
 

+ 2 - 14
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__ */

+ 156 - 270
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);
 
+  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();
   }
-
-  audio_debug("FmodAudioSound::play()  Sound should be playing (or played if it is really short)." );
-
+  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();
 
-  result = _channel->setPosition( startTime , FMOD_TIMEUNIT_MS );
-  ERRCHECK(result);
+  int startTime = start_time * 1000;
 
+  result = _channel->setPosition( startTime , FMOD_TIMEUNIT_MS );
+  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( &current_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, &center, &sub, &backleft, &backright, &sideleft, &sideright );
+  fmod_audio_errcheck(result);
+
   switch(speaker) {
   
   case 1: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = frontleft;
     break;
   case 2: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = frontright;
     break;
   case 3: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = center;
     break;
   case 4: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = sub;
     break;
   case 5: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = backleft;
     break;
   case 6: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = backright;
     break;
   case 7: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &sub, &backleft, &backright, &sideleft, &sideright );
-    ERRCHECK(result);
     returnValue = sideleft;
     break;
   case 8: 
-    result = _channel->getSpeakerMix( &frontleft, &frontright, &center, &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);;
-}
-
-////////////////////////////////////////////////////////////////////
-//     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);;
+  set_speaker_mix_or_balance_on_channel();
 }
 
-
-
 ////////////////////////////////////////////////////////////////////
 //     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.' ");

+ 7 - 0
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!
   ////////////////////////////////////////////////////////////