Panda3D

openalAudioSound.h

00001 // Filename: openalAudioSound.h
00002 // Created by:  Ben Buchwald <bb2@alumni.cmu.edu>
00003 //
00004 //
00005 ////////////////////////////////////////////////////////////////////
00006 //
00007 // PANDA 3D SOFTWARE
00008 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00009 //
00010 // All use of this software is subject to the terms of the revised BSD
00011 // license.  You should have received a copy of this license along
00012 // with this source code in a file named "LICENSE."
00013 //
00014 ////////////////////////////////////////////////////////////////////
00015 
00016 
00017 
00018 #ifndef __OPENAL_AUDIO_SOUND_H__
00019 #define __OPENAL_AUDIO_SOUND_H__
00020 
00021 #include "pandabase.h"
00022 
00023 #ifdef HAVE_OPENAL //[
00024 
00025 #include "audioSound.h"
00026 #include "movieAudioCursor.h"
00027 #include "trueClock.h"
00028 
00029 // OSX uses the OpenAL framework
00030 #ifdef IS_OSX
00031   #include <OpenAL/al.h>
00032   #include <OpenAL/alc.h>
00033 #else
00034   #include <AL/al.h>
00035   #include <AL/alc.h>
00036 #endif
00037 
00038 class EXPCL_OPENAL_AUDIO OpenALAudioSound : public AudioSound {
00039   friend class OpenALAudioManager;
00040 
00041 public:
00042 
00043   ~OpenALAudioSound();
00044 
00045   // For best compatibility, set the loop_count, start_time,
00046   // volume, and balance, prior to calling play().  You may
00047   // set them while they're playing, but it's implementation
00048   // specific whether you get the results.
00049   void play();
00050   void stop();
00051 
00052   // loop: false = play once; true = play forever.
00053   // inits to false.
00054   void set_loop(bool loop=true);
00055   bool get_loop() const;
00056 
00057   // loop_count: 0 = forever; 1 = play once; n = play n times.
00058   // inits to 1.
00059   void set_loop_count(unsigned long loop_count=1);
00060   unsigned long get_loop_count() const;
00061 
00062   // 0 = beginning; length() = end.
00063   // inits to 0.0.
00064   void set_time(PN_stdfloat time=0.0);
00065   PN_stdfloat get_time() const;
00066 
00067   // 0 = minimum; 1.0 = maximum.
00068   // inits to 1.0.
00069   void set_volume(PN_stdfloat volume=1.0);
00070   PN_stdfloat get_volume() const;
00071 
00072   // -1.0 is hard left
00073   // 0.0 is centered
00074   // 1.0 is hard right
00075   // inits to 0.0.
00076   void set_balance(PN_stdfloat balance_right=0.0);
00077   PN_stdfloat get_balance() const;
00078 
00079   // play_rate is any positive float value.
00080   // inits to 1.0.
00081   void set_play_rate(PN_stdfloat play_rate=1.0f);
00082   PN_stdfloat get_play_rate() const;
00083 
00084   // inits to manager's state.
00085   void set_active(bool active=true);
00086   bool get_active() const;
00087 
00088   // This is the string that throw_event() will throw
00089   // when the sound finishes playing.  It is not triggered
00090   // when the sound is stopped with stop().
00091   void set_finished_event(const string& event);
00092   const string& get_finished_event() const;
00093 
00094   const string &get_name() const;
00095 
00096   // return: playing time in seconds.
00097   PN_stdfloat length() const;
00098 
00099   // Controls the position of this sound's emitter.
00100   // pos is a pointer to an xyz triplet of the emitter's position.
00101   // vel is a pointer to an xyz triplet of the emitter's velocity.
00102   void set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz);
00103   void get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz);
00104 
00105   void set_3d_min_distance(PN_stdfloat dist);
00106   PN_stdfloat get_3d_min_distance() const;
00107 
00108   void set_3d_max_distance(PN_stdfloat dist);
00109   PN_stdfloat get_3d_max_distance() const;
00110 
00111   void set_3d_drop_off_factor(PN_stdfloat factor);
00112   PN_stdfloat get_3d_drop_off_factor() const;
00113 
00114   AudioSound::SoundStatus status() const;
00115 
00116   void finished();
00117 
00118 private:
00119   OpenALAudioSound(OpenALAudioManager* manager, 
00120                    MovieAudio *movie,
00121                    bool positional,
00122                    int mode);
00123   INLINE void   set_calibrated_clock(double rtc, double t, double playrate);
00124   INLINE double get_calibrated_clock(double rtc) const;
00125   void          correct_calibrated_clock(double rtc, double t);
00126   void          cache_time(double rtc);
00127   void cleanup();
00128   void restart_stalled_audio();
00129   void delete_queued_buffers();
00130   ALuint make_buffer(int samples, int channels, int rate, unsigned char *data);
00131   void queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset);
00132   int  read_stream_data(int bytelen, unsigned char *data);
00133   void pull_used_buffers();
00134   void push_fresh_buffers();
00135   INLINE void require_sound_data();
00136   INLINE void release_sound_data();
00137 
00138 private:
00139 
00140   void do_stop();
00141 
00142   PT(MovieAudio) _movie;
00143   OpenALAudioManager::SoundData *_sd;
00144 
00145   struct QueuedBuffer {
00146     ALuint _buffer;
00147     int    _samples;
00148     int    _loop_index;
00149     double _time_offset;
00150   };
00151 
00152   int    _playing_loops;
00153   PN_stdfloat  _playing_rate;
00154 
00155   pdeque<QueuedBuffer> _stream_queued;
00156   int                  _loops_completed;
00157 
00158   ALuint _source;
00159   PT(OpenALAudioManager) _manager;
00160 
00161   PN_stdfloat _volume; // 0..1.0
00162   PN_stdfloat _balance; // -1..1
00163   PN_stdfloat _play_rate; // 0..1.0
00164 
00165   bool _positional;
00166   ALfloat _location[3];
00167   ALfloat _velocity[3];
00168 
00169   PN_stdfloat _min_dist;
00170   PN_stdfloat _max_dist;
00171   PN_stdfloat _drop_off_factor;
00172 
00173   double _length;
00174   int    _loop_count;
00175 
00176   int    _desired_mode;
00177 
00178   // The calibrated clock is initialized when the
00179   // sound starts playing, and is periodically corrected
00180   // thereafter.
00181   double _calibrated_clock_base;
00182   double _calibrated_clock_scale;
00183   double _calibrated_clock_decavg;
00184 
00185   // The start_time field affects the next call to play.
00186   double _start_time;
00187 
00188   // The current_time field is updated every frame
00189   // during the AudioManager update.  Updates need
00190   // to be atomic, because get_time can be called
00191   // in the cull thread.
00192   PN_stdfloat  _current_time;
00193 
00194   // This is the string that throw_event() will throw
00195   // when the sound finishes playing.  It is not triggered
00196   // when the sound is stopped with stop().
00197   string _finished_event;
00198 
00199   Filename _basename;
00200 
00201   // _active is for things like a 'turn off sound effects' in
00202   // a preferences pannel.
00203   // _active is not about whether a sound is currently playing.
00204   // Use status() for info on whether the sound is playing.
00205   bool _active;
00206   bool _paused;
00207 
00208  public:
00209   static TypeHandle get_class_type() {
00210     return _type_handle;
00211   }
00212   static void init_type() {
00213     AudioSound::init_type();
00214     register_type(_type_handle, "OpenALAudioSound", AudioSound::get_class_type());
00215   }
00216   virtual TypeHandle get_type() const {
00217     return get_class_type();
00218   }
00219   virtual TypeHandle force_init_type() {
00220     init_type();
00221     return get_class_type();
00222   }
00223 
00224  private:
00225   static TypeHandle _type_handle;
00226 
00227   ////////////////////////////////////////////////////////////
00228   //DONE
00229   ////////////////////////////////////////////////////////////
00230 };
00231 
00232 #include "openalAudioSound.I"
00233 
00234 #endif //]
00235 
00236 #endif /* __OPENAL_AUDIO_SOUND_H__ */
 All Classes Functions Variables Enumerations