SGSampleGroup::SGSampleGroup () :
_smgr(NULL),
_active(false),
- _changed(true),
- _position_changed(true),
_position(SGVec3d::zeros().data()),
- _orientation(SGVec3f::zeros().data())
+ _orientation(SGVec3f::zeros().data()),
+ _tied_to_listener(false)
{
_samples.clear();
}
SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) :
_smgr(smgr),
_active(false),
- _changed(true),
- _position_changed(true),
_position(SGVec3d::zeros().data()),
- _orientation(SGVec3f::zeros().data())
+ _orientation(SGVec3f::zeros().data()),
+ _tied_to_listener(false)
{
_smgr->add(this, refname);
_active = _smgr->is_working();
if ( sample->is_valid_source() && sample->is_playing() ) {
sample->no_valid_source();
_smgr->release_source( sample->get_source() );
+ _smgr->release_buffer( sample );
}
}
//
// a request to start playing a sound has been filed.
//
- ALboolean looping = sample->get_looping() ? AL_TRUE : AL_FALSE;
+ if ( _smgr->request_buffer(sample) == SGSoundMgr::NO_BUFFER )
+ continue;
- if ( !sample->is_valid_buffer() ) {
- // sample was not yet loaded or removed again
-
-// TODO: Create a buffer cache that checks whether a file is already present
-// as an OpenAL buffer since buffers can be shared among sources.
- load_file(sample);
- if ( testForALError("load sample") ) {
- throw sg_exception("Failed to load sound sample.");
- continue;
- }
-
- // create an OpenAL buffer handle
- ALuint buffer;
- alGenBuffers(1, &buffer);
- if ( testForALError("generate buffer") ) {
- throw sg_exception("Failed to generate OpenAL buffer.");
- continue;
- }
-
- // Copy data to the internal OpenAL buffer
- const ALvoid *data = sample->get_data();
- ALenum format = sample->get_format();
- ALsizei size = sample->get_size();
- ALsizei freq = sample->get_frequency();
- alBufferData( buffer, format, data, size, freq );
- sample->free_data();
- if ( testForALError("buffer add data") ) {
- continue;
- }
-
- sample->set_buffer(buffer);
+ if ( _tied_to_listener && _smgr->has_changed() ) {
+ sample->set_base_position( _smgr->get_position_vec() );
+ sample->set_orientation( _smgr->get_direction() );
+ sample->set_velocity( _smgr->get_velocity() );
}
// start playing the sample
+ ALboolean looping = sample->get_looping() ? AL_TRUE : AL_FALSE;
ALuint buffer = sample->get_buffer();
ALuint source = _smgr->request_source();
if (alIsSource(source) == AL_TRUE && alIsBuffer(buffer) == AL_TRUE)
alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
alSourcei( source, AL_LOOPING, looping );
+ alSourcef( source, AL_ROLLOFF_FACTOR, 1.2 );
alSourcePlay( source );
testForALError("sample play");
} else {
sample->no_valid_source();
sample->stop();
_smgr->release_source( source );
-
}
}
testForALError("update");
return false;
}
- _samples.erase( sample_it );
+ // remove the sources buffer
+ _smgr->release_buffer( sample_it->second );
+ _samples.erase( refname );
+
return true;
}
return;
}
- sample_map_iterator sample_current = _samples.begin();
- sample_map_iterator sample_end = _samples.end();
- for ( ; sample_current != sample_end; ++sample_current ) {
- SGSoundSample *sample = sample_current->second;
- sample->set_base_position( pos );
+ if ( !_tied_to_listener ) {
+ sample_map_iterator sample_current = _samples.begin();
+ sample_map_iterator sample_end = _samples.end();
+ for ( ; sample_current != sample_end; ++sample_current ) {
+ SGSoundSample *sample = sample_current->second;
+ sample->set_base_position( pos );
+ }
}
}
alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() );
testForALError("audio cone");
- alSourcef( source, AL_ROLLOFF_FACTOR, 1.0 );
alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() );
alSourcef( source, AL_REFERENCE_DISTANCE,
sample->get_reference_dist() );
}
}
-ALvoid
-SGSampleGroup::load_file(SGSoundSample *sample) {
- if (sample->is_file()) {
- unsigned int size;
- int freq, format;
- void *data;
-
- string sample_name = sample->get_sample_name();
- _smgr->load(sample_name, &data, &format, &size, &freq);
-
- sample->set_data( (unsigned char *)data );
- sample->set_frequency( freq );
- sample->set_format( format );
- sample->set_size( size );
- }
-}
-
void SGSampleGroup::set_volume( float vol )
{
_volume = vol;