Panda3D
|
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