This patch creates a sample manager next to the sound manager. The
difference between the two is this: A sample is file related and sound is a authonomus entity. This means you can have several sounds pointing to a single sample. In that case, just one sample is loaded into memory. The advantage is you can play the same sample with different pitch or volume, but with just one sample loaded into memory. To fully support this there is a new fucntion call: FGSimpleSound *sample = new FGSimpleSound("filename"); mgr->add(sample, "name"); should be replaced by: FGSimpleSound *sample = mgr->add("name", "filename"); But the old behaviour is still supported with one minor change, sounds with the same name aren't supported anymore. Erik
This commit is contained in:
parent
1f5096105b
commit
d8b6786d20
3 changed files with 127 additions and 29 deletions
|
@ -37,12 +37,13 @@
|
|||
|
||||
FGSound::FGSound(const SGPropertyNode * node)
|
||||
: _name(""),
|
||||
_sample(0),
|
||||
_factor(1.0),
|
||||
_active(false),
|
||||
_mode(FGSound::ONCE),
|
||||
_type(FGSound::LEVEL)
|
||||
_type(FGSound::LEVEL),
|
||||
_node(node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
FGSound::~FGSound()
|
||||
|
@ -53,7 +54,6 @@ FGSound::~FGSound()
|
|||
void
|
||||
FGSound::init()
|
||||
{
|
||||
FGSoundMgr * mgr = globals->get_soundmgr();
|
||||
vector<const SGPropertyNode *> kids;
|
||||
float p = 0.0;
|
||||
float v = 0.0;
|
||||
|
@ -204,12 +204,10 @@ FGSound::init()
|
|||
//
|
||||
// Initialize the sample
|
||||
//
|
||||
_sample = new FGSimpleSound(_node->getStringValue("path"));
|
||||
FGSoundMgr * mgr = globals->get_soundmgr();
|
||||
_sample = mgr->add(_name, _node->getStringValue("path"));
|
||||
_sample->set_volume(v);
|
||||
_sample->set_pitch(p);
|
||||
|
||||
if (!mgr->exists(_name))
|
||||
mgr->add(_sample, _name);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -235,12 +233,22 @@ FGSound::update (int dt)
|
|||
// if (!_property)
|
||||
// return;
|
||||
|
||||
i = _property->getFloatValue() * _factor;
|
||||
if (_type == FGSound::INVERTED)
|
||||
i = !i;
|
||||
|
||||
if ((_type == FGSound::LEVEL) || (_type == FGSound::INVERTED)) {
|
||||
if (i == 0) {
|
||||
|
||||
//
|
||||
// If the sound is already playing we have nothing to do.
|
||||
//
|
||||
if (_active && (_mode == FGSound::ONCE))
|
||||
return;
|
||||
|
||||
int check = _property->getFloatValue() * _factor;
|
||||
if (_type == FGSound::INVERTED)
|
||||
check = !check;
|
||||
|
||||
//
|
||||
// If the state changes to false, stop playing.
|
||||
//
|
||||
if (check == 0) {
|
||||
_active = false;
|
||||
if (mgr->is_playing(_name)) {
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name);
|
||||
|
@ -250,12 +258,10 @@ FGSound::update (int dt)
|
|||
return;
|
||||
}
|
||||
|
||||
if (_active && (_mode == FGSound::ONCE))
|
||||
return;
|
||||
|
||||
} else { // FGSound::FLIPFLOP
|
||||
|
||||
if ((bool)i == _active)
|
||||
bool check = _property->getFloatValue() * _factor;
|
||||
if (check == _active)
|
||||
return;
|
||||
|
||||
//
|
||||
|
@ -272,6 +278,7 @@ FGSound::update (int dt)
|
|||
// Update the volume
|
||||
//
|
||||
int max = _volume.size();
|
||||
|
||||
double volume = 1.0, volume_offset = 0.0;
|
||||
for(i = 0; i < max; i++) {
|
||||
double v = _volume[i].prop->getDoubleValue();
|
||||
|
|
|
@ -81,11 +81,25 @@ FGSoundMgr::FGSoundMgr() {
|
|||
// destructor
|
||||
|
||||
FGSoundMgr::~FGSoundMgr() {
|
||||
sound_map_iterator current = sounds.begin();
|
||||
sound_map_iterator end = sounds.end();
|
||||
for ( ; current != end; ++current ) {
|
||||
FGSimpleSound *s = current->second;
|
||||
delete s->get_sample();
|
||||
|
||||
//
|
||||
// Remove the samples from the sample manager.
|
||||
//
|
||||
sample_map_iterator sample_current = samples.begin();
|
||||
sample_map_iterator sample_end = samples.end();
|
||||
for ( ; sample_current != sample_end; ++sample_current ) {
|
||||
sample_ref *sr = sample_current->second;
|
||||
delete sr->sample;
|
||||
delete sr;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove the sounds from the sound manager.
|
||||
//
|
||||
sound_map_iterator sound_current = sounds.begin();
|
||||
sound_map_iterator sound_end = sounds.end();
|
||||
for ( ; sound_current != sound_end; ++sound_current ) {
|
||||
FGSimpleSound *s = sound_current->second;
|
||||
delete s;
|
||||
}
|
||||
|
||||
|
@ -102,10 +116,26 @@ void FGSoundMgr::init() {
|
|||
// audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
|
||||
audio_sched -> setSafetyMargin ( FG_SOUND_SAFETY_MULT * safety ) ;
|
||||
|
||||
sound_map_iterator current = sounds.begin();
|
||||
sound_map_iterator end = sounds.end();
|
||||
for ( ; current != end; ++current ) {
|
||||
FGSimpleSound *s = current->second;
|
||||
|
||||
//
|
||||
// Remove the samples from the sample manager.
|
||||
//
|
||||
sample_map_iterator sample_current = samples.begin();
|
||||
sample_map_iterator sample_end = samples.end();
|
||||
for ( ; sample_current != sample_end; ++sample_current ) {
|
||||
sample_ref *sr = sample_current->second;
|
||||
delete sr->sample;
|
||||
delete sr;
|
||||
}
|
||||
samples.clear();
|
||||
|
||||
//
|
||||
// Remove the sounds from the sound manager.
|
||||
//
|
||||
sound_map_iterator sound_current = sounds.begin();
|
||||
sound_map_iterator sound_end = sounds.end();
|
||||
for ( ; sound_current != sound_end; ++sound_current ) {
|
||||
FGSimpleSound *s = sound_current->second;
|
||||
delete s->get_sample();
|
||||
delete s;
|
||||
}
|
||||
|
@ -150,11 +180,52 @@ void FGSoundMgr::update(int dt) {
|
|||
|
||||
// add a sound effect, return true if successful
|
||||
bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname ) {
|
||||
|
||||
sample_map_iterator it = samples.find(refname);
|
||||
if (it != samples.end())
|
||||
return false;
|
||||
|
||||
sample_ref *sr = new sample_ref;
|
||||
|
||||
sr->n=1;
|
||||
sr->sample = sound->get_sample();
|
||||
samples[refname] = sr;
|
||||
|
||||
sounds[refname] = sound;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// add a sound from a file, return the sample if successful, else return NULL
|
||||
FGSimpleSound *FGSoundMgr::add( const string& refname, const string &file ) {
|
||||
FGSimpleSound *sound;
|
||||
|
||||
if (file == (string)"")
|
||||
return NULL;
|
||||
|
||||
sample_map_iterator it = samples.find(file);
|
||||
if (it == samples.end()) {
|
||||
sound = new FGSimpleSound(file);
|
||||
sounds[refname] = sound;
|
||||
|
||||
sample_ref *sr = new sample_ref;
|
||||
|
||||
sr->n=1;
|
||||
sr->sample = sound->get_sample();
|
||||
samples[file] = sr;
|
||||
|
||||
} else {
|
||||
sample_ref *sr = it->second;
|
||||
|
||||
sr->n++;
|
||||
sound =
|
||||
new FGSimpleSound(sr->sample->getBuffer(), sr->sample->getLength());
|
||||
sounds[refname] = sound;
|
||||
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
// remove a sound effect, return true if successful
|
||||
bool FGSoundMgr::remove( const string& refname ) {
|
||||
|
@ -182,7 +253,12 @@ bool FGSoundMgr::remove( const string& refname ) {
|
|||
// cout << "Still playing " << sample->get_sample()->getPlayCount()
|
||||
// << " instances!" << endl;
|
||||
|
||||
delete sample;
|
||||
//
|
||||
// FIXME:
|
||||
// Due to the change in the sound manager, samples live
|
||||
// until the sound manager gets removed.
|
||||
//
|
||||
// delete sample;
|
||||
sounds.erase( it );
|
||||
|
||||
return true;
|
||||
|
|
|
@ -79,6 +79,16 @@ public:
|
|||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
slSample *sample;
|
||||
} sample_ref;
|
||||
|
||||
typedef map < string, sample_ref * > sample_map;
|
||||
typedef sample_map::iterator sample_map_iterator;
|
||||
typedef sample_map::const_iterator const_sample_map_iterator;
|
||||
|
||||
|
||||
typedef map < string, FGSimpleSound * > sound_map;
|
||||
typedef sound_map::iterator sound_map_iterator;
|
||||
typedef sound_map::const_iterator const_sound_map_iterator;
|
||||
|
@ -89,7 +99,9 @@ class FGSoundMgr : public FGSubsystem
|
|||
|
||||
slScheduler *audio_sched;
|
||||
smMixer *audio_mixer;
|
||||
|
||||
sound_map sounds;
|
||||
sample_map samples;
|
||||
|
||||
SGTimeStamp last;
|
||||
double safety;
|
||||
|
@ -130,6 +142,9 @@ public:
|
|||
// add a sound effect, return true if successful
|
||||
bool add( FGSimpleSound *sound, const string& refname);
|
||||
|
||||
// add a sound file, return the sample if successful, else return NULL
|
||||
FGSimpleSound *add( const string& refname, const string& file = "" );
|
||||
|
||||
// remove a sound effect, return true if successful
|
||||
bool remove( const string& refname );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue