Panda3D
openalAudioSound.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file openalAudioSound.I
10  * @author Ben Buchwald <bb2@alumni.cmu.edu>
11  */
12 
13 /**
14  * Sets the sound's calibrated clock.
15  *
16  * OpenAL is not very accurate at reporting how much time has elapsed within a
17  * buffer. However, it does accurately report when it has finished playing a
18  * buffer. So we use a hybrid clock algorithm. When OpenAL is in the middle
19  * of a buffer, we use a real-time-clock to estimate how far the sound has
20  * gotten. Each time OpenAL reaches the end of a buffer (which it does every
21  * 1/4 second or so), we calibrate our real-time-clock by speeding it up or
22  * slowing it down.
23  */
24 INLINE void OpenALAudioSound::
25 set_calibrated_clock(double rtc, double t, double accel) {
26  _calibrated_clock_scale = _playing_rate * accel;
27  _calibrated_clock_base = rtc - (t / _calibrated_clock_scale);
28 }
29 
30 /**
31  * Returns the value of the calibrated clock.
32  */
33 INLINE double OpenALAudioSound::
34 get_calibrated_clock(double rtc) const {
35  return (rtc - _calibrated_clock_base) * _calibrated_clock_scale;
36 }
37 
38 /**
39  * Makes sure the sound data record is present, and if not, obtains it.
40  *
41  * Returns true on success, false on failure.
42  */
43 INLINE bool OpenALAudioSound::
44 require_sound_data() {
45  if (_sd==0) {
46  _sd = _manager->get_sound_data(_movie, _desired_mode);
47  if (_sd==0) {
48  audio_error("Could not open audio " << _movie->get_filename());
49  return false;
50  }
51  }
52  return true;
53 }
54 
55 /**
56  * Checks if the sound data record is present and releasable, and if so,
57  * releases it.
58  *
59  * The sound data is "releasable" if it's from an ordinary, local file. Remote
60  * streams cannot necessarily be reopened if lost, so we'll hold onto them if
61  * so. The `force` argument overrides this, indicating we don't intend to
62  * reacquire the sound data.
63  */
64 INLINE void OpenALAudioSound::
65 release_sound_data(bool force) {
66  if (!has_sound_data()) return;
67 
68  if (force || !_movie->get_filename().empty()) {
69  _manager->decrement_client_count(_sd);
70  _sd = 0;
71  }
72 }
73 
74 /**
75  * Checks if the sound has NOT been cleaned up yet.
76  */
77 INLINE bool OpenALAudioSound::
78 is_valid() const {
79  return _manager != nullptr;
80 }
81 
82 /**
83  * Checks if the sound is playing. This is per the OpenALAudioManager's
84  * definition of "playing" -- as in, "will be called upon every update"
85  *
86  * This is mainly intended for use in asserts.
87  */
88 INLINE bool OpenALAudioSound::
89 is_playing() const {
90  // Manager only gives us a _source if we need it (to talk to OpenAL), so:
91  return _source != 0;
92 }
93 
94 /**
95  * Checks if the sound has its SoundData structure open at the moment.
96  *
97  * This is mainly intended for use in asserts.
98  */
99 INLINE bool OpenALAudioSound::
100 has_sound_data() const {
101  return _sd != nullptr;
102 }