Panda3D
openalAudioSound.h
1 // Filename: openalAudioSound.h
2 // Created by: Ben Buchwald <bb2@alumni.cmu.edu>
3 //
4 //
5 ////////////////////////////////////////////////////////////////////
6 //
7 // PANDA 3D SOFTWARE
8 // Copyright (c) Carnegie Mellon University. All rights reserved.
9 //
10 // All use of this software is subject to the terms of the revised BSD
11 // license. You should have received a copy of this license along
12 // with this source code in a file named "LICENSE."
13 //
14 ////////////////////////////////////////////////////////////////////
15 
16 #ifndef __OPENAL_AUDIO_SOUND_H__
17 #define __OPENAL_AUDIO_SOUND_H__
18 
19 #include "pandabase.h"
20 
21 #include "audioSound.h"
22 #include "movieAudioCursor.h"
23 #include "trueClock.h"
24 #include "openalAudioManager.h"
25 
26 // OSX uses the OpenAL framework
27 #ifdef IS_OSX
28  #include <OpenAL/al.h>
29  #include <OpenAL/alc.h>
30 #else
31  #include <AL/al.h>
32  #include <AL/alc.h>
33 #endif
34 
35 class EXPCL_OPENAL_AUDIO OpenALAudioSound : public AudioSound {
36  friend class OpenALAudioManager;
37 
38 public:
39 
41 
42  // For best compatibility, set the loop_count, start_time,
43  // volume, and balance, prior to calling play(). You may
44  // set them while they're playing, but it's implementation
45  // specific whether you get the results.
46  void play();
47  void stop();
48 
49  // loop: false = play once; true = play forever.
50  // inits to false.
51  void set_loop(bool loop=true);
52  bool get_loop() const;
53 
54  // loop_count: 0 = forever; 1 = play once; n = play n times.
55  // inits to 1.
56  void set_loop_count(unsigned long loop_count=1);
57  unsigned long get_loop_count() const;
58 
59  // 0 = beginning; length() = end.
60  // inits to 0.0.
61  void set_time(PN_stdfloat time=0.0);
62  PN_stdfloat get_time() const;
63 
64  // 0 = minimum; 1.0 = maximum.
65  // inits to 1.0.
66  void set_volume(PN_stdfloat volume=1.0);
67  PN_stdfloat get_volume() const;
68 
69  // -1.0 is hard left
70  // 0.0 is centered
71  // 1.0 is hard right
72  // inits to 0.0.
73  void set_balance(PN_stdfloat balance_right=0.0);
74  PN_stdfloat get_balance() const;
75 
76  // play_rate is any positive float value.
77  // inits to 1.0.
78  void set_play_rate(PN_stdfloat play_rate=1.0f);
79  PN_stdfloat get_play_rate() const;
80 
81  // inits to manager's state.
82  void set_active(bool active=true);
83  bool get_active() const;
84 
85  // This is the string that throw_event() will throw
86  // when the sound finishes playing. It is not triggered
87  // when the sound is stopped with stop().
88  void set_finished_event(const string& event);
89  const string& get_finished_event() const;
90 
91  const string &get_name() const;
92 
93  // return: playing time in seconds.
94  PN_stdfloat length() const;
95 
96  // Controls the position of this sound's emitter.
97  // pos is a pointer to an xyz triplet of the emitter's position.
98  // vel is a pointer to an xyz triplet of the emitter's velocity.
99  void set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz);
100  void get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz);
101 
102  void set_3d_min_distance(PN_stdfloat dist);
103  PN_stdfloat get_3d_min_distance() const;
104 
105  void set_3d_max_distance(PN_stdfloat dist);
106  PN_stdfloat get_3d_max_distance() const;
107 
108  void set_3d_drop_off_factor(PN_stdfloat factor);
109  PN_stdfloat get_3d_drop_off_factor() const;
110 
111  AudioSound::SoundStatus status() const;
112 
113  void finished();
114 
115 private:
117  MovieAudio *movie,
118  bool positional,
119  int mode);
120  INLINE void set_calibrated_clock(double rtc, double t, double playrate);
121  INLINE double get_calibrated_clock(double rtc) const;
122  void correct_calibrated_clock(double rtc, double t);
123  void cache_time(double rtc);
124  void cleanup();
125  void restart_stalled_audio();
126  void delete_queued_buffers();
127  ALuint make_buffer(int samples, int channels, int rate, unsigned char *data);
128  void queue_buffer(ALuint buffer, int samples, int loop_index, double time_offset);
129  int read_stream_data(int bytelen, unsigned char *data);
130  void pull_used_buffers();
131  void push_fresh_buffers();
132  INLINE void require_sound_data();
133  INLINE void release_sound_data();
134 
135 private:
136 
137  void do_stop();
138 
139  PT(MovieAudio) _movie;
140  OpenALAudioManager::SoundData *_sd;
141 
142  struct QueuedBuffer {
143  ALuint _buffer;
144  int _samples;
145  int _loop_index;
146  double _time_offset;
147  };
148 
149  int _playing_loops;
150  PN_stdfloat _playing_rate;
151 
152  pdeque<QueuedBuffer> _stream_queued;
153  int _loops_completed;
154 
155  ALuint _source;
156  PT(OpenALAudioManager) _manager;
157 
158  PN_stdfloat _volume; // 0..1.0
159  PN_stdfloat _balance; // -1..1
160  PN_stdfloat _play_rate; // 0..1.0
161 
162  bool _positional;
163  ALfloat _location[3];
164  ALfloat _velocity[3];
165 
166  PN_stdfloat _min_dist;
167  PN_stdfloat _max_dist;
168  PN_stdfloat _drop_off_factor;
169 
170  double _length;
171  int _loop_count;
172 
173  int _desired_mode;
174 
175  // The calibrated clock is initialized when the
176  // sound starts playing, and is periodically corrected
177  // thereafter.
178  double _calibrated_clock_base;
179  double _calibrated_clock_scale;
180  double _calibrated_clock_decavg;
181 
182  // The start_time field affects the next call to play.
183  double _start_time;
184 
185  // The current_time field is updated every frame
186  // during the AudioManager update. Updates need
187  // to be atomic, because get_time can be called
188  // in the cull thread.
189  PN_stdfloat _current_time;
190 
191  // This is the string that throw_event() will throw
192  // when the sound finishes playing. It is not triggered
193  // when the sound is stopped with stop().
194  string _finished_event;
195 
196  Filename _basename;
197 
198  // _active is for things like a 'turn off sound effects' in
199  // a preferences pannel.
200  // _active is not about whether a sound is currently playing.
201  // Use status() for info on whether the sound is playing.
202  bool _active;
203  bool _paused;
204 
205  public:
206  static TypeHandle get_class_type() {
207  return _type_handle;
208  }
209  static void init_type() {
210  AudioSound::init_type();
211  register_type(_type_handle, "OpenALAudioSound", AudioSound::get_class_type());
212  }
213  virtual TypeHandle get_type() const {
214  return get_class_type();
215  }
216  virtual TypeHandle force_init_type() {
217  init_type();
218  return get_class_type();
219  }
220 
221  private:
222  static TypeHandle _type_handle;
223 
224  ////////////////////////////////////////////////////////////
225  //DONE
226  ////////////////////////////////////////////////////////////
227 };
228 
229 #include "openalAudioSound.I"
230 
231 #endif /* __OPENAL_AUDIO_SOUND_H__ */
virtual void set_volume(PN_stdfloat)
Sets listener gain.
PN_stdfloat get_play_rate() const
get the overall speed/pitch/play rate
virtual PN_stdfloat get_volume() const
Gets listener gain.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
void set_play_rate(PN_stdfloat play_rate)
set the overall play rate
virtual void set_active(bool)
Turn on/off Warning: not implemented.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition: movieAudio.h:48