mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
finish callbacks
This commit is contained in:
parent
4c6b2a4698
commit
de34468d87
@ -27,3 +27,27 @@ INLINE bool GlobalMilesManager::
|
||||
is_open() const {
|
||||
return _is_open;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GlobalMilesManager::get_num_samples
|
||||
// Access: Public
|
||||
// Description: Returns the number of sample handles that have been
|
||||
// allocated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GlobalMilesManager::
|
||||
get_num_samples() const {
|
||||
MutexHolder holder(_samples_lock);
|
||||
return _samples.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GlobalMilesManager::get_num_sequences
|
||||
// Access: Public
|
||||
// Description: Returns the number of sequence handles that have been
|
||||
// allocated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GlobalMilesManager::
|
||||
get_num_sequences() const {
|
||||
MutexHolder holder(_sequences_lock);
|
||||
return _sequences.size();
|
||||
}
|
||||
|
@ -25,11 +25,16 @@
|
||||
#include "mss.h"
|
||||
#include "pset.h"
|
||||
#include "pmutex.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
#ifndef UINTa
|
||||
#define UINTa U32
|
||||
#endif
|
||||
|
||||
#ifndef SINTa
|
||||
#define SINTa S32
|
||||
#endif
|
||||
|
||||
class MilesAudioSample;
|
||||
class MilesAudioSequence;
|
||||
|
||||
@ -51,9 +56,11 @@ public:
|
||||
|
||||
bool get_sample(HSAMPLE &sample, size_t &index, MilesAudioSample *sound);
|
||||
void release_sample(size_t index, MilesAudioSample *sound);
|
||||
INLINE int get_num_samples() const;
|
||||
|
||||
bool get_sequence(HSEQUENCE &sequence, size_t &index, MilesAudioSequence *sound);
|
||||
void release_sequence(size_t index, MilesAudioSequence *sound);
|
||||
INLINE int get_num_sequences() const;
|
||||
|
||||
void force_midi_reset();
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "nullAudioSound.h"
|
||||
#include "string_utils.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "reMutexHolder.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -52,7 +53,9 @@ PT(AudioManager) Create_AudioManager() {
|
||||
// Miles resources.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MilesAudioManager::
|
||||
MilesAudioManager() : _streams_lock("MilesAudioManager::_streams_lock"),
|
||||
MilesAudioManager() :
|
||||
_lock("MilesAudioManager::_lock"),
|
||||
_streams_lock("MilesAudioManager::_streams_lock"),
|
||||
_streams_cvar(_streams_lock)
|
||||
{
|
||||
audio_debug("MilesAudioManager::MilesAudioManager(), this = "
|
||||
@ -68,6 +71,7 @@ MilesAudioManager() : _streams_lock("MilesAudioManager::_streams_lock"),
|
||||
_concurrent_sound_limit = 0;
|
||||
_is_valid = true;
|
||||
_hasMidiSounds = false;
|
||||
_sounds_finished = false;
|
||||
|
||||
// We used to hang a call to a force-shutdown function on atexit(),
|
||||
// so that any running sounds (particularly MIDI sounds) would be
|
||||
@ -125,22 +129,8 @@ shutdown() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MilesAudioManager::
|
||||
is_valid() {
|
||||
bool check=true;
|
||||
if (_sounds.size() != _lru.size()) {
|
||||
audio_debug("-- Error _sounds.size() != _lru.size() --");
|
||||
check=false;
|
||||
} else {
|
||||
LRU::const_iterator i=_lru.begin();
|
||||
for (; i != _lru.end(); ++i) {
|
||||
SoundMap::const_iterator smi=_sounds.find(**i);
|
||||
if (smi == _sounds.end()) {
|
||||
audio_debug("-- "<<**i<<" in _lru and not in _sounds --");
|
||||
check=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _is_valid && check;
|
||||
ReMutexHolder holder(_lock);
|
||||
return do_is_valid();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -149,15 +139,15 @@ is_valid() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(AudioSound) MilesAudioManager::
|
||||
get_sound(const string& file_name, bool) {
|
||||
get_sound(const string &file_name, bool) {
|
||||
ReMutexHolder holder(_lock);
|
||||
audio_debug("MilesAudioManager::get_sound(file_name=\""<<file_name<<"\")");
|
||||
|
||||
if(!is_valid()) {
|
||||
if (!do_is_valid()) {
|
||||
audio_debug("invalid MilesAudioManager returning NullSound");
|
||||
return get_null_sound();
|
||||
}
|
||||
|
||||
assert(is_valid());
|
||||
Filename path = file_name;
|
||||
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
@ -172,6 +162,7 @@ get_sound(const string& file_name, bool) {
|
||||
// ...found the sound in the cache.
|
||||
sd = (*si).second;
|
||||
audio_debug(" sound found in pool 0x" << (void*)sd);
|
||||
|
||||
} else {
|
||||
// ...the sound was not found in the cache/pool.
|
||||
sd = load(path);
|
||||
@ -183,11 +174,11 @@ get_sound(const string& file_name, bool) {
|
||||
// The following is roughly like: _sounds[path] = sd;
|
||||
// But, it gives us an iterator into the map.
|
||||
pair<SoundMap::const_iterator, bool> ib
|
||||
=_sounds.insert(SoundMap::value_type(path, sd));
|
||||
= _sounds.insert(SoundMap::value_type(path, sd));
|
||||
if (!ib.second) {
|
||||
// The insert failed.
|
||||
audio_debug(" failed map insert of "<<path);
|
||||
assert(is_valid());
|
||||
nassertr(do_is_valid(), NULL);
|
||||
return get_null_sound();
|
||||
}
|
||||
// Set si, so that we can get a reference to the path
|
||||
@ -228,7 +219,7 @@ get_sound(const string& file_name, bool) {
|
||||
}
|
||||
|
||||
audio_debug(" returning 0x" << (void*)audioSound);
|
||||
assert(is_valid());
|
||||
nassertr(do_is_valid(), NULL);
|
||||
return audioSound;
|
||||
}
|
||||
|
||||
@ -238,10 +229,11 @@ get_sound(const string& file_name, bool) {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
uncache_sound(const string& file_name) {
|
||||
uncache_sound(const string &file_name) {
|
||||
audio_debug("MilesAudioManager::uncache_sound(file_name=\""
|
||||
<<file_name<<"\")");
|
||||
assert(is_valid());
|
||||
ReMutexHolder holder(_lock);
|
||||
nassertv(do_is_valid());
|
||||
Filename path = file_name;
|
||||
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
@ -249,15 +241,15 @@ uncache_sound(const string& file_name) {
|
||||
vfs->resolve_filename(path, get_model_path());
|
||||
|
||||
audio_debug(" path=\""<<path<<"\"");
|
||||
SoundMap::iterator i=_sounds.find(path);
|
||||
SoundMap::iterator i = _sounds.find(path);
|
||||
if (i != _sounds.end()) {
|
||||
assert(_lru.size()>0);
|
||||
LRU::iterator lru_i=find(_lru.begin(), _lru.end(), &(i->first));
|
||||
assert(lru_i != _lru.end());
|
||||
nassertv(_lru.size() > 0);
|
||||
LRU::iterator lru_i = find(_lru.begin(), _lru.end(), &(i->first));
|
||||
nassertv(lru_i != _lru.end());
|
||||
_lru.erase(lru_i);
|
||||
_sounds.erase(i);
|
||||
}
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -268,10 +260,8 @@ uncache_sound(const string& file_name) {
|
||||
void MilesAudioManager::
|
||||
clear_cache() {
|
||||
audio_debug("MilesAudioManager::clear_cache()");
|
||||
if (_is_valid) { assert(is_valid()); }
|
||||
_sounds.clear();
|
||||
_lru.clear();
|
||||
if (_is_valid) { assert(is_valid()); }
|
||||
ReMutexHolder holder(_lock);
|
||||
do_clear_cache();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -281,13 +271,15 @@ clear_cache() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
set_cache_limit(unsigned int count) {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
audio_debug("MilesAudioManager::set_cache_limit(count="<<count<<")");
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
while (_lru.size() > count) {
|
||||
uncache_a_sound();
|
||||
}
|
||||
_cache_limit=count;
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -308,10 +300,11 @@ get_cache_limit() const {
|
||||
void MilesAudioManager::
|
||||
set_volume(float volume) {
|
||||
audio_debug("MilesAudioManager::set_volume(volume="<<volume<<")");
|
||||
if (_volume!=volume) {
|
||||
ReMutexHolder holder(_lock);
|
||||
if (_volume != volume) {
|
||||
_volume = volume;
|
||||
// Tell our AudioSounds to adjust:
|
||||
AudioSet::iterator i=_sounds_on_loan.begin();
|
||||
AudioSet::iterator i = _sounds_on_loan.begin();
|
||||
for (; i!=_sounds_on_loan.end(); ++i) {
|
||||
(*i)->set_volume((*i)->get_volume());
|
||||
}
|
||||
@ -336,11 +329,12 @@ get_volume() const {
|
||||
void MilesAudioManager::
|
||||
set_play_rate(float play_rate) {
|
||||
audio_debug("MilesAudioManager::set_play_rate(play_rate="<<play_rate<<")");
|
||||
if (_play_rate!=play_rate) {
|
||||
ReMutexHolder holder(_lock);
|
||||
if (_play_rate != play_rate) {
|
||||
_play_rate = play_rate;
|
||||
// Tell our AudioSounds to adjust:
|
||||
AudioSet::iterator i=_sounds_on_loan.begin();
|
||||
for (; i!=_sounds_on_loan.end(); ++i) {
|
||||
AudioSet::iterator i = _sounds_on_loan.begin();
|
||||
for (; i != _sounds_on_loan.end(); ++i) {
|
||||
(*i)->set_play_rate((*i)->get_play_rate());
|
||||
}
|
||||
}
|
||||
@ -364,11 +358,12 @@ get_play_rate() const {
|
||||
void MilesAudioManager::
|
||||
set_active(bool active) {
|
||||
audio_debug("MilesAudioManager::set_active(flag="<<active<<")");
|
||||
if (_active!=active) {
|
||||
ReMutexHolder holder(_lock);
|
||||
if (_active != active) {
|
||||
_active=active;
|
||||
// Tell our AudioSounds to adjust:
|
||||
AudioSet::iterator i=_sounds_on_loan.begin();
|
||||
for (; i!=_sounds_on_loan.end(); ++i) {
|
||||
AudioSet::iterator i = _sounds_on_loan.begin();
|
||||
for (; i != _sounds_on_loan.end(); ++i) {
|
||||
(*i)->set_active(_active);
|
||||
}
|
||||
|
||||
@ -395,8 +390,9 @@ get_active() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
set_concurrent_sound_limit(unsigned int limit) {
|
||||
ReMutexHolder holder(_lock);
|
||||
_concurrent_sound_limit = limit;
|
||||
reduce_sounds_playing_to(_concurrent_sound_limit);
|
||||
do_reduce_sounds_playing_to(_concurrent_sound_limit);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -411,17 +407,13 @@ get_concurrent_sound_limit() const {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::reduce_sounds_playing_to
|
||||
// Access: Private, Virtual
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
reduce_sounds_playing_to(unsigned int count) {
|
||||
int limit = _sounds_playing.size() - count;
|
||||
while (limit-- > 0) {
|
||||
SoundsPlaying::iterator sound = _sounds_playing.begin();
|
||||
assert(sound != _sounds_playing.end());
|
||||
(**sound).stop();
|
||||
}
|
||||
ReMutexHolder holder(_lock);
|
||||
do_reduce_sounds_playing_to(count);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -444,12 +436,33 @@ stop_all_sounds() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
update() {
|
||||
MutexHolder holder(_streams_lock);
|
||||
{
|
||||
MutexHolder holder(_streams_lock);
|
||||
if (_stream_thread.is_null() && !_streams.empty()) {
|
||||
// If we don't have a sub-thread, we have to service the streams
|
||||
// in the main thread.
|
||||
do_service_streams();
|
||||
}
|
||||
}
|
||||
|
||||
if (_stream_thread.is_null() && !_streams.empty()) {
|
||||
// If we don't have a sub-thread, we have to service the streams
|
||||
// in the main thread.
|
||||
do_service_streams();
|
||||
if (_sounds_finished) {
|
||||
_sounds_finished = false;
|
||||
|
||||
// If the _sounds_finished flag was set, we should scan our list
|
||||
// of playing sounds and see if any of them have finished
|
||||
// recently. We don't do this in the finished callback, because
|
||||
// that might have been called in a sub-thread (and we may not
|
||||
// have threading supported--and mutex protection--compiled in).
|
||||
|
||||
SoundsPlaying::iterator si = _sounds_playing.begin();
|
||||
while (si != _sounds_playing.end()) {
|
||||
MilesAudioSound *sound = (*si);
|
||||
++si;
|
||||
|
||||
if (sound->status() == AudioSound::READY) {
|
||||
sound->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,6 +475,7 @@ void MilesAudioManager::
|
||||
release_sound(MilesAudioSound *audioSound) {
|
||||
audio_debug("MilesAudioManager::release_sound(audioSound=\""
|
||||
<<audioSound->get_name()<<"\"), this = " << (void *)this);
|
||||
ReMutexHolder holder(_lock);
|
||||
AudioSet::iterator ai = _sounds_on_loan.find(audioSound);
|
||||
nassertv(ai != _sounds_on_loan.end());
|
||||
_sounds_on_loan.erase(ai);
|
||||
@ -480,6 +494,7 @@ void MilesAudioManager::
|
||||
cleanup() {
|
||||
audio_debug("MilesAudioManager::cleanup(), this = " << (void *)this
|
||||
<< ", _cleanup_required = " << _cleanup_required);
|
||||
ReMutexHolder holder(_lock);
|
||||
if (!_cleanup_required) {
|
||||
return;
|
||||
}
|
||||
@ -490,7 +505,7 @@ cleanup() {
|
||||
(*ai)->cleanup();
|
||||
}
|
||||
|
||||
clear_cache();
|
||||
do_clear_cache();
|
||||
|
||||
// Now stop the thread, if it has been started.
|
||||
if (!_stream_thread.is_null()) {
|
||||
@ -519,6 +534,7 @@ cleanup() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
output(ostream &out) const {
|
||||
ReMutexHolder holder(_lock);
|
||||
out << get_type() << ": " << _sounds_playing.size()
|
||||
<< " / " << _sounds_on_loan.size() << " sounds playing / total";
|
||||
}
|
||||
@ -530,15 +546,88 @@ output(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
write(ostream &out) const {
|
||||
ReMutexHolder holder(_lock);
|
||||
|
||||
out << (*this) << "\n";
|
||||
AudioSet::const_iterator ai;
|
||||
for (ai = _sounds_on_loan.begin(); ai != _sounds_on_loan.end(); ++ai) {
|
||||
MilesAudioSound *sound = (*ai);
|
||||
out << " " << *sound << "\n";
|
||||
}
|
||||
|
||||
{
|
||||
MutexHolder holder(_streams_lock);
|
||||
out << _streams.size() << " streams opened.\n";
|
||||
if (!_stream_thread.is_null()) {
|
||||
out << "(Audio streaming thread has been started.)\n";
|
||||
}
|
||||
}
|
||||
|
||||
GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
|
||||
|
||||
int num_samples = mgr->get_num_samples();
|
||||
out << num_samples << " sample handles allocated globally.\n";
|
||||
|
||||
int num_sequences = mgr->get_num_sequences();
|
||||
out << num_sequences << " sequence handles allocated globally.\n";
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::do_is_valid
|
||||
// Access: Private
|
||||
// Description: Implementation of is_valid(). Assumes the lock is
|
||||
// already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MilesAudioManager::
|
||||
do_is_valid() {
|
||||
bool check = true;
|
||||
if (_sounds.size() != _lru.size()) {
|
||||
audio_debug("-- Error _sounds.size() != _lru.size() --");
|
||||
check = false;
|
||||
|
||||
} else {
|
||||
LRU::const_iterator i = _lru.begin();
|
||||
for (; i != _lru.end(); ++i) {
|
||||
SoundMap::const_iterator smi = _sounds.find(**i);
|
||||
if (smi == _sounds.end()) {
|
||||
audio_debug("-- "<<**i<<" in _lru and not in _sounds --");
|
||||
check = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _is_valid && check;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::do_reduce_sounds_playing_to
|
||||
// Access: Private
|
||||
// Description: Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
do_reduce_sounds_playing_to(unsigned int count) {
|
||||
int limit = _sounds_playing.size() - count;
|
||||
while (limit-- > 0) {
|
||||
SoundsPlaying::iterator sound = _sounds_playing.begin();
|
||||
assert(sound != _sounds_playing.end());
|
||||
(**sound).stop();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::do_clear_cache
|
||||
// Access: Private
|
||||
// Description: Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
do_clear_cache() {
|
||||
if (_is_valid) { nassertv(do_is_valid()); }
|
||||
_sounds.clear();
|
||||
_lru.clear();
|
||||
if (_is_valid) { nassertv(do_is_valid()); }
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::start_service_stream
|
||||
// Access: Private
|
||||
@ -580,7 +669,7 @@ stop_service_stream(HSTREAM stream) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::most_recently_used
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description: Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
most_recently_used(const string &path) {
|
||||
@ -593,18 +682,18 @@ most_recently_used(const string &path) {
|
||||
// At this point, path should not exist in the _lru:
|
||||
assert(find(_lru.begin(), _lru.end(), &path) == _lru.end());
|
||||
_lru.push_back(&path);
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioManager::uncache_a_sound
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description: Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
uncache_a_sound() {
|
||||
audio_debug("MilesAudioManager::uncache_a_sound()");
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
// uncache least recently used:
|
||||
assert(_lru.size()>0);
|
||||
LRU::reference path=_lru.front();
|
||||
@ -616,7 +705,7 @@ uncache_a_sound() {
|
||||
audio_debug(" uncaching \""<<i->first<<"\"");
|
||||
_sounds.erase(i);
|
||||
}
|
||||
assert(is_valid());
|
||||
nassertv(do_is_valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -626,8 +715,9 @@ uncache_a_sound() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
starting_sound(MilesAudioSound *audio) {
|
||||
ReMutexHolder holder(_lock);
|
||||
if (_concurrent_sound_limit) {
|
||||
reduce_sounds_playing_to(_concurrent_sound_limit);
|
||||
do_reduce_sounds_playing_to(_concurrent_sound_limit);
|
||||
}
|
||||
_sounds_playing.insert(audio);
|
||||
}
|
||||
@ -641,6 +731,7 @@ starting_sound(MilesAudioSound *audio) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioManager::
|
||||
stopping_sound(MilesAudioSound *audio) {
|
||||
ReMutexHolder holder(_lock);
|
||||
_sounds_playing.erase(audio);
|
||||
if (_hasMidiSounds && _sounds_playing.size() == 0) {
|
||||
GlobalMilesManager::get_global_ptr()->force_midi_reset();
|
||||
@ -654,6 +745,8 @@ stopping_sound(MilesAudioSound *audio) {
|
||||
// Description: Reads a sound file and allocates a SoundData pointer
|
||||
// for it. Returns NULL if the sound file cannot be
|
||||
// loaded.
|
||||
//
|
||||
// Assumes the lock is already held.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(MilesAudioManager::SoundData) MilesAudioManager::
|
||||
load(const Filename &file_name) {
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "pvector.h"
|
||||
#include "thread.h"
|
||||
#include "pmutex.h"
|
||||
#include "reMutex.h"
|
||||
#include "conditionVar.h"
|
||||
|
||||
class MilesAudioSound;
|
||||
@ -65,7 +66,6 @@ public:
|
||||
virtual unsigned int get_concurrent_sound_limit() const;
|
||||
|
||||
virtual void reduce_sounds_playing_to(unsigned int count);
|
||||
|
||||
virtual void stop_all_sounds();
|
||||
|
||||
virtual void update();
|
||||
@ -78,6 +78,10 @@ public:
|
||||
virtual void write(ostream &out) const;
|
||||
|
||||
private:
|
||||
bool do_is_valid();
|
||||
void do_reduce_sounds_playing_to(unsigned int count);
|
||||
void do_clear_cache();
|
||||
|
||||
void start_service_stream(HSTREAM stream);
|
||||
void stop_service_stream(HSTREAM stream);
|
||||
|
||||
@ -123,12 +127,12 @@ private:
|
||||
// The offspring of this manager:
|
||||
AudioSet _sounds_on_loan;
|
||||
|
||||
typedef pset<MilesAudioSound* > SoundsPlaying;
|
||||
typedef pset<MilesAudioSound *> SoundsPlaying;
|
||||
// The sounds from this manager that are currently playing:
|
||||
SoundsPlaying _sounds_playing;
|
||||
|
||||
// The Least Recently Used mechanism:
|
||||
typedef pdeque<const string* > LRU;
|
||||
typedef pdeque<const string *> LRU;
|
||||
LRU _lru;
|
||||
// State:
|
||||
float _volume;
|
||||
@ -141,6 +145,10 @@ private:
|
||||
bool _is_valid;
|
||||
bool _hasMidiSounds;
|
||||
|
||||
// This mutex protects everything above.
|
||||
ReMutex _lock;
|
||||
bool _sounds_finished;
|
||||
|
||||
typedef pvector<HSTREAM> Streams;
|
||||
PT(StreamThread) _stream_thread;
|
||||
Streams _streams;
|
||||
|
@ -96,6 +96,8 @@ play() {
|
||||
&_sd->_raw_data[0], _sd->_raw_data.size(),
|
||||
0);
|
||||
_original_playback_rate = AIL_sample_playback_rate(_sample);
|
||||
AIL_set_sample_user_data(_sample, 0, (SINTa)this);
|
||||
AIL_register_EOS_callback(_sample, finish_callback);
|
||||
|
||||
set_volume(_volume);
|
||||
set_play_rate(_play_rate);
|
||||
@ -293,6 +295,19 @@ cleanup() {
|
||||
stop();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioSample::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MilesAudioSample::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << " " << get_name() << " " << status();
|
||||
if (!_sd.is_null()) {
|
||||
out << " " << (_sd->_raw_data.size() + 1023) / 1024 << "K";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioSample::internal_stop
|
||||
// Access: Private
|
||||
@ -306,4 +321,20 @@ internal_stop() {
|
||||
_sample_index = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioSample::finish_callback
|
||||
// Access: Private, Static
|
||||
// Description: This callback is made by Miles (possibly in a
|
||||
// sub-thread) when the sample finishes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AILCALLBACK MilesAudioSample::
|
||||
finish_callback(HSAMPLE sample) {
|
||||
MilesAudioSample *self = (MilesAudioSample *)AIL_sample_user_data(sample, 0);
|
||||
if (milesAudio_cat.is_debug()) {
|
||||
milesAudio_cat.debug()
|
||||
<< "finished " << *self << "\n";
|
||||
}
|
||||
self->_manager->_sounds_finished = true;
|
||||
}
|
||||
|
||||
#endif //]
|
||||
|
@ -56,9 +56,11 @@ public:
|
||||
virtual AudioSound::SoundStatus status() const;
|
||||
|
||||
virtual void cleanup();
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
void internal_stop();
|
||||
static void AILCALLBACK finish_callback(HSAMPLE sample);
|
||||
|
||||
PT(MilesAudioManager::SoundData) _sd;
|
||||
HSAMPLE _sample;
|
||||
|
@ -92,6 +92,8 @@ play() {
|
||||
_sequence = 0;
|
||||
} else {
|
||||
AIL_init_sequence(_sequence, &_sd->_raw_data[0], 0);
|
||||
AIL_set_sequence_user_data(_sequence, 0, (SINTa)this);
|
||||
AIL_register_sequence_callback(_sequence, finish_callback);
|
||||
|
||||
set_volume(_volume);
|
||||
set_play_rate(_play_rate);
|
||||
@ -296,4 +298,20 @@ internal_stop() {
|
||||
_sequence_index = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioSequence::finish_callback
|
||||
// Access: Private, Static
|
||||
// Description: This callback is made by Miles (possibly in a
|
||||
// sub-thread) when the sequence finishes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AILCALLBACK MilesAudioSequence::
|
||||
finish_callback(HSEQUENCE sequence) {
|
||||
MilesAudioSequence *self = (MilesAudioSequence *)AIL_sequence_user_data(sequence, 0);
|
||||
if (milesAudio_cat.is_debug()) {
|
||||
milesAudio_cat.debug()
|
||||
<< "finished " << *self << "\n";
|
||||
}
|
||||
self->_manager->_sounds_finished = true;
|
||||
}
|
||||
|
||||
#endif //]
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
|
||||
private:
|
||||
void internal_stop();
|
||||
static void AILCALLBACK finish_callback(HSEQUENCE sequence);
|
||||
|
||||
PT(MilesAudioManager::SoundData) _sd;
|
||||
HSEQUENCE _sequence;
|
||||
|
@ -77,6 +77,14 @@ play() {
|
||||
if (_stream == 0) {
|
||||
GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
|
||||
_stream = AIL_open_stream(mgr->_digital_driver, _path.c_str(), 0);
|
||||
if (_stream == 0) {
|
||||
milesAudio_cat.warning()
|
||||
<< "Could not play " << _file_name << ": too many open streams\n";
|
||||
return;
|
||||
}
|
||||
AIL_set_stream_user_data(_stream, 0, (SINTa)this);
|
||||
AIL_register_stream_callback(_stream, finish_callback);
|
||||
|
||||
} else {
|
||||
// We already had the stream open. Keep it open; just restart
|
||||
// it.
|
||||
@ -84,29 +92,24 @@ play() {
|
||||
_manager->stop_service_stream(_stream);
|
||||
}
|
||||
|
||||
if (_stream == 0) {
|
||||
milesAudio_cat.warning()
|
||||
<< "Could not play " << _file_name << ": too many open streams\n";
|
||||
|
||||
// Start playing:
|
||||
nassertv(_stream != 0);
|
||||
HSAMPLE sample = AIL_stream_sample_handle(_stream);
|
||||
nassertv(sample != 0);
|
||||
|
||||
_original_playback_rate = AIL_sample_playback_rate(sample);
|
||||
set_volume(_volume);
|
||||
set_play_rate(_play_rate);
|
||||
|
||||
AIL_set_stream_loop_count(_stream, _loop_count);
|
||||
|
||||
if (miles_audio_panda_threads) {
|
||||
AIL_auto_service_stream(_stream, 0);
|
||||
_manager->start_service_stream(_stream);
|
||||
} else {
|
||||
// Start playing:
|
||||
HSAMPLE sample = AIL_stream_sample_handle(_stream);
|
||||
nassertv(sample != 0);
|
||||
|
||||
_original_playback_rate = AIL_sample_playback_rate(sample);
|
||||
set_volume(_volume);
|
||||
set_play_rate(_play_rate);
|
||||
|
||||
AIL_set_stream_loop_count(_stream, _loop_count);
|
||||
|
||||
if (miles_audio_panda_threads) {
|
||||
AIL_auto_service_stream(_stream, 0);
|
||||
_manager->start_service_stream(_stream);
|
||||
} else {
|
||||
AIL_auto_service_stream(_stream, 1);
|
||||
}
|
||||
AIL_start_stream(_stream);
|
||||
AIL_auto_service_stream(_stream, 1);
|
||||
}
|
||||
AIL_start_stream(_stream);
|
||||
|
||||
} else {
|
||||
// In case _loop_count gets set to forever (zero):
|
||||
@ -295,5 +298,21 @@ cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MilesAudioStream::finish_callback
|
||||
// Access: Private, Static
|
||||
// Description: This callback is made by Miles (possibly in a
|
||||
// sub-thread) when the stream finishes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AILCALLBACK MilesAudioStream::
|
||||
finish_callback(HSTREAM stream) {
|
||||
MilesAudioStream *self = (MilesAudioStream *)AIL_stream_user_data(stream, 0);
|
||||
if (milesAudio_cat.is_debug()) {
|
||||
milesAudio_cat.debug()
|
||||
<< "finished " << *self << "\n";
|
||||
}
|
||||
self->_manager->_sounds_finished = true;
|
||||
}
|
||||
|
||||
|
||||
#endif //]
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
virtual void cleanup();
|
||||
|
||||
private:
|
||||
static void AILCALLBACK finish_callback(HSTREAM stream);
|
||||
|
||||
Filename _path;
|
||||
HSTREAM _stream;
|
||||
S32 _original_playback_rate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user