Panda3D

fmodAudioSound.h

00001 // Filename: fmodAudioSound.h
00002 // Created by:  cort (January 22, 2003)
00003 // Prior system by: cary
00004 // Rewrite [for new Version of FMOD-EX] by: Stan Rosenbaum "Staque" - Spring 2006
00005 //
00006 //
00007 ////////////////////////////////////////////////////////////////////
00008 //
00009 // PANDA 3D SOFTWARE
00010 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00011 //
00012 // All use of this software is subject to the terms of the revised BSD
00013 // license.  You should have received a copy of this license along
00014 // with this source code in a file named "LICENSE."
00015 //
00016 ////////////////////////////////////////////////////////////////////
00017 //
00018 //
00019 //
00020 ////////////////////////////////////////////////////////////////////
00021 //
00022 // [FIRST READ FmodAudioManager for an Introduction if you haven't
00023 // already].
00024 //
00025 // Hello, all future Panda audio code people! This is my errata
00026 // documentation to Help any future programmer maintain FMOD and PANDA.
00027 //
00028 // Well, if you reading this you probably want to know how PANDA deals
00029 // with sounds directly using FMOD-EX. Well I am going to tell you.
00030 //
00031 // The first thing, you as the programmer have to understand,
00032 // especially if you never have done sound programming before, is how
00033 // the FMOD-EX API works.
00034 //
00035 // With FMOD-EX the guys at Firelight, adopted a model of managing
00036 // sounds with FMOD similar to how a Sound Designer creates sound in a
00037 // sound studio using SOUNDS and CHANNELS. Although this may seem
00038 // strange at first, if you are not familiar with sound programming,
00039 // there is a very good metaphor you are probably already familiar with
00040 // to explain how FMOD-EX works.
00041 //
00042 // Think of you standard GUI API. Usually a GUI API is made up of two
00043 // things: Windows and Widgets. These correspond to CHANNELS and
00044 // SOUNDS, where a Channel is a Window and a Sound is Widget. Sounds
00045 // are played within channels, and channels don't exist unless they
00046 // have something to display.
00047 //
00048 // Now why am I explaining all of this? When PANDA was created they set
00049 // up the basic audio classes to handle only the idea of a SOUND. The
00050 // idea of a Channel really wasn't prevalent as in more modern Audio
00051 // APIs. With this rewrite of PANDA to use the FMOD-EX API, the PANDA
00052 // FmodAudioSound Class, now has to handle two different parts of the
00053 // FMOD-EX API in order to play a sound.
00054 //
00055 // SOUND: The object the handles the audio data in form of WAV, AIF,
00056 // OGG, MID, IT, MP3, etc... And CHANNEL: The object that actually
00057 // plays the sound and manipulates it in real time.
00058 //
00059 // Ultimately this isn't a problem expect for a couple situations when
00060 // you go to play a sound, which I will explain in more detail in that
00061 // part of the code. All that you have to know right now is that
00062 // Channels in FMOD do not exist unless they are playing a sound. And
00063 // in the PANDA FmodAudioSound API class there is only ONE dedicated
00064 // channel per sound.  Otherwise there is really nothing to worry
00065 // about.
00066 //
00067 ////////////////////////////////////////////////////////////////////
00068 
00069 
00070 
00071 #ifndef __FMOD_AUDIO_SOUND_H__
00072 #define __FMOD_AUDIO_SOUND_H__
00073 
00074 #include <pandabase.h>
00075 
00076 #ifdef HAVE_FMODEX //[
00077 
00078 #include "audioSound.h"
00079 
00080 #include <fmod.hpp>
00081 #include <fmod_errors.h>
00082 
00083 class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound {
00084  public:
00085 
00086   FmodAudioSound(AudioManager *manager, Filename fn, bool positional );
00087   ~FmodAudioSound();
00088 
00089   // For best compatibility, set the loop_count, start_time,
00090   // volume, and balance, prior to calling play().  You may
00091   // set them while they're playing, but it's implementation
00092   // specific whether you get the results.
00093   void play();
00094   void stop();
00095 
00096   // loop: false = play once; true = play forever.
00097   // inits to false.
00098   void set_loop(bool loop=true);
00099   bool get_loop() const;
00100 
00101   // loop_count: 0 = forever; 1 = play once; n = play n times.
00102   // inits to 1.
00103   void set_loop_count(unsigned long loop_count=1);
00104   unsigned long get_loop_count() const;
00105 
00106   // 0 = beginning; length() = end.
00107   // inits to 0.0.
00108   void set_time(float start_time=0.0);
00109   float get_time() const;
00110 
00111   // 0 = minimum; 1.0 = maximum.
00112   // inits to 1.0.
00113   void set_volume(float volume=1.0);
00114   float get_volume() const;
00115 
00116   // -1.0 is hard left
00117   // 0.0 is centered
00118   // 1.0 is hard right
00119   // inits to 0.0.
00120   void set_balance(float balance_right=0.0);
00121   float get_balance() const;
00122 
00123   // play_rate is any positive float value.
00124   // inits to 1.0.
00125   void set_play_rate(float play_rate=1.0f);
00126   float get_play_rate() const;
00127 
00128   const string &get_name() const;
00129 
00130   // return: playing time in seconds.
00131   float length() const;
00132 
00133   // Controls the position of this sound's emitter.
00134   // pos is a pointer to an xyz triplet of the emitter's position.
00135   // vel is a pointer to an xyz triplet of the emitter's velocity.
00136   void set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz);
00137   void get_3d_attributes(float *px, float *py, float *pz, float *vx, float *vy, float *vz);
00138 
00139   void set_3d_min_distance(float dist);
00140   float get_3d_min_distance() const;
00141 
00142   void set_3d_max_distance(float dist);
00143   float get_3d_max_distance() const;
00144 
00145   AudioSound::SoundStatus status() const;
00146 
00147   virtual float get_speaker_mix(AudioManager::SpeakerId speaker);
00148   virtual void set_speaker_mix(float frontleft, float frontright, float center, float sub, float backleft, float backright, float sideleft, float  sideright);
00149 
00150   void set_active(bool active=true);
00151   bool get_active() const;
00152 
00153   void finished();
00154   void set_finished_event(const string& event);
00155   const string& get_finished_event() const;
00156 
00157  private:
00158   PT(FmodAudioManager) _manager;
00159   FMOD::Sound      *_sound;
00160   FMOD::Channel    *_channel;
00161 
00162   Filename _file_name;
00163 
00164   float _volume; 
00165   float _balance;
00166   float _playrate;
00167   int   _priority;
00168   float _mix[AudioManager::SPK_COUNT];
00169 
00170   float _sampleFrequency;
00171   mutable float _length;   //in seconds.
00172 
00173   FMOD_SPEAKERMODE  _speakermode;
00174 
00175   FMOD_VECTOR _location;
00176   FMOD_VECTOR _velocity;
00177 
00178   float _min_dist;
00179   float _max_dist;
00180 
00181   void start_playing();
00182   void set_volume_on_channel();
00183   void set_balance_on_channel();
00184   void set_play_rate_on_channel();
00185   void set_speaker_mix_on_channel();
00186   void set_3d_attributes_on_channel();
00187   // void add_dsp_on_channel();
00188   void set_speaker_mix_or_balance_on_channel();
00189 
00190   virtual int get_priority();
00191   virtual void set_priority(int priority);
00192 
00193   bool _active;
00194   bool _paused;
00195   float _start_time;
00196 
00197   string _finished_event;
00198 
00199   // This reference-counting pointer is set to this while the sound is
00200   // playing, and cleared when we get an indication that the sound has
00201   // stopped.  This prevents a sound from destructing while it is
00202   // playing.  We use a PT instead of managing the reference counts by
00203   // hand to help guard against accidental reference count leaks or
00204   // other mismanagement.
00205   PT(FmodAudioSound) _self_ref;
00206 
00207   friend FMOD_RESULT F_CALLBACK sound_end_callback(FMOD_CHANNEL *  channel, 
00208                                                    FMOD_CHANNEL_CALLBACKTYPE  type, 
00209                                                    void *commanddata1, 
00210                                                    void *commanddata2);
00211 
00212   ////////////////////////////////////////////////////////////
00213   //These are needed for Panda's Pointer System. DO NOT ERASE!
00214   ////////////////////////////////////////////////////////////
00215 
00216  public:
00217   static TypeHandle get_class_type() {
00218     return _type_handle;
00219   }
00220   static void init_type() {
00221     AudioSound::init_type();
00222     register_type(_type_handle, "FmodAudioSound", AudioSound::get_class_type());
00223   }
00224   virtual TypeHandle get_type() const {
00225     return get_class_type();
00226   }
00227   virtual TypeHandle force_init_type() {
00228     init_type();
00229     return get_class_type();
00230   }
00231 
00232  private:
00233   static TypeHandle _type_handle;
00234 
00235   ////////////////////////////////////////////////////////////
00236   //DONE
00237   ////////////////////////////////////////////////////////////
00238 };
00239 
00240 #include "fmodAudioSound.I"
00241 
00242 #endif //]
00243 
00244 #endif /* __FMOD_AUDIO_SOUND_H__ */
00245 
00246 
00247 
00248 
00249 
 All Classes Functions Variables Enumerations