#include <simgear/misc/sg_path.hxx>
#include <simgear/math/SGMath.hxx>
+extern bool isNaN(float *v);
#define MAX_SOURCES 128
_volume(0.0),
_device(NULL),
_context(NULL),
- _position(SGVec3d::zeros()),
+ _absolute_pos(SGVec3d::zeros()),
+ _offset_pos(SGVec3d::zeros()),
+ _base_pos(SGVec3d::zeros()),
_velocity(SGVec3d::zeros()),
_orientation(SGQuatd::zeros()),
_devname(NULL)
// initialize the sound manager
void SGSoundMgr::init() {
-printf("Initializing OpenAL sound manager\n");
SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
ALCdevice *device = alcOpenDevice(_devname);
alDopplerFactor(1.0);
alDopplerVelocity(340.3); // speed of sound in meters per second.
- if ( alIsExtensionPresent((const ALchar*)"EXT_exponent_distance") ) {
- alDistanceModel(AL_EXPONENT_DISTANCE);
- } else {
- alDistanceModel(AL_INVERSE_DISTANCE);
- }
+ // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
+ // AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE));
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
testForALError("listener initialization");
else break;
}
-printf("%i free sources found\n", _free_sources.size() );
if (_free_sources.size() == 0) {
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to grab any OpenAL sources!");
}
// stop the sound manager
void SGSoundMgr::stop() {
if (_working) {
-printf("Stopping Sound Manager\n");
_working = false;
_active = false;
void SGSoundMgr::suspend() {
if (_working) {
-printf("SoundManager suspend\n");
sample_group_map_iterator sample_grp_current = _sample_groups.begin();
sample_group_map_iterator sample_grp_end = _sample_groups.end();
for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) {
void SGSoundMgr::resume() {
if (_working) {
-printf("SoundManager resume\n");
sample_group_map_iterator sample_grp_current = _sample_groups.begin();
sample_group_map_iterator sample_grp_end = _sample_groups.end();
for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) {
void SGSoundMgr::bind ()
{
-printf("SoundManager bind\n");
_free_sources.clear();
_free_sources.reserve( MAX_SOURCES );
_sources_in_use.clear();
void SGSoundMgr::unbind ()
{
-printf("SoundManager unbind\n");
_sample_groups.clear();
// delete free sources
}
// run the audio scheduler
-void SGSoundMgr::update_late( double dt ) {
+void SGSoundMgr::update( double dt ) {
if (_active) {
+ if (_changed) {
+ update_pos_and_orientation();
+ }
+
sample_group_map_iterator sample_grp_current = _sample_groups.begin();
sample_group_map_iterator sample_grp_end = _sample_groups.end();
for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) {
}
if (_changed) {
+#if 0
+if (isNaN(_at_up_vec)) printf("NaN in listener orientation\n");
+if (isNaN(toVec3f(_absolute_pos).data())) printf("NaN in listener position\n");
+if (isNaN(_velocity.data())) printf("NaN in listener velocity\n");
+#endif
alListenerf( AL_GAIN, _volume );
alListenerfv( AL_ORIENTATION, _at_up_vec );
- alListenerfv( AL_POSITION, toVec3f(_position).data() );
- alListenerfv( AL_VELOCITY, toVec3f(_velocity).data() );
+ // alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() );
+ alListenerfv( AL_VELOCITY, _velocity.data() );
// alDopplerVelocity(340.3); // TODO: altitude dependent
testForALError("update");
_changed = false;
// sample group was not found.
if (create) {
SGSampleGroup* sgrp = new SGSampleGroup(this, refname);
+ add( sgrp, refname );
return sgrp;
}
else
_changed = true;
}
-/**
- * set the orientation of the listener (in opengl coordinates)
- *
- * Description: ORIENTATION is a pair of 3-tuples representing the
- * 'at' direction vector and 'up' direction of the Object in
- * Cartesian space. AL expects two vectors that are orthogonal to
- * each other. These vectors are not expected to be normalized. If
- * one or more vectors have zero length, implementation behavior
- * is undefined. If the two vectors are linearly dependent,
- * behavior is undefined.
- */
-void SGSoundMgr::set_orientation( SGQuatd ori )
-{
- _orientation = ori;
-
- SGVec3d sgv_up = ori.rotate(SGVec3d::e2());
- SGVec3d sgv_at = ori.rotate(SGVec3d::e3());
- _at_up_vec[0] = sgv_at[0];
- _at_up_vec[1] = sgv_at[1];
- _at_up_vec[2] = sgv_at[2];
- _at_up_vec[3] = sgv_up[0];
- _at_up_vec[4] = sgv_up[1];
- _at_up_vec[5] = sgv_up[2];
- _changed = true;
-}
-
// Get an unused source id
//
// The Sound Manager should keep track of the sources in use, the distance
_free_sources.pop_back();
_sources_in_use.push_back(source);
}
+ else
+ SG_LOG( SG_GENERAL, SG_INFO, "No more free sources available\n");
return source;
}
void *data;
load(sample_name, &data, &format, &size, &freq);
- std::auto_ptr<unsigned char> ptr;
- ptr.reset((unsigned char *)data);
-
- sample->set_data( ptr );
+ sample->set_data( &data );
sample->set_frequency( freq );
sample->set_format( format );
sample->set_size( size );
}
}
}
- else
+ else {
buffer = sample->get_buffer();
+}
return buffer;
}
}
}
+void SGSoundMgr::update_pos_and_orientation() {
+ /**
+ * Description: ORIENTATION is a pair of 3-tuples representing the
+ * 'at' direction vector and 'up' direction of the Object in
+ * Cartesian space. AL expects two vectors that are orthogonal to
+ * each other. These vectors are not expected to be normalized. If
+ * one or more vectors have zero length, implementation behavior
+ * is undefined. If the two vectors are linearly dependent,
+ * behavior is undefined.
+ *
+ * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
+ */
+ SGVec3d sgv_at = _orientation.backTransform(-SGVec3d::e3());
+ SGVec3d sgv_up = _orientation.backTransform(SGVec3d::e2());
+ _at_up_vec[0] = sgv_at[0];
+ _at_up_vec[1] = sgv_at[1];
+ _at_up_vec[2] = sgv_at[2];
+ _at_up_vec[3] = sgv_up[0];
+ _at_up_vec[4] = sgv_up[1];
+ _at_up_vec[5] = sgv_up[2];
+
+ // static const SGQuatd q(-0.5, -0.5, 0.5, 0.5);
+ // SGQuatd hlOr = SGQuatd::fromLonLat(SGGeod::fromCart(_base_pos));
+ // SGQuatd ec2body = hlOr*_orientation;
+ _absolute_pos = _base_pos; // + ec2body.backTransform( _offset_pos );
+}
+
bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt,
size_t *sz, int *frq )
{