SGSampleGroup::SGSampleGroup () :
_smgr(NULL),
+ _refname(""),
_active(false),
- _position(SGVec3d::zeros().data()),
- _orientation(SGVec3f::zeros().data()),
- _tied_to_listener(false)
+ _tied_to_listener(false),
+ _position(SGVec3d::zeros()),
+ _velocity(SGVec3f::zeros()),
+ _orientation(SGVec3f::zeros())
{
_samples.clear();
}
SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) :
_smgr(smgr),
+ _refname(refname),
_active(false),
- _position(SGVec3d::zeros().data()),
- _orientation(SGVec3f::zeros().data()),
- _tied_to_listener(false)
+ _tied_to_listener(false),
+ _position(SGVec3d::zeros()),
+ _velocity(SGVec3f::zeros()),
+ _orientation(SGVec3f::zeros())
{
_smgr->add(this, refname);
_active = _smgr->is_working();
- _refname = refname;
_samples.clear();
}
return;
}
- if ( !_tied_to_listener ) {
+ if ( !_tied_to_listener && _position != pos ) {
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 );
}
+ _position = pos;
}
}
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_velocity( vel );
+ if (_velocity != vel) {
+ 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_velocity( vel );
+ }
}
}
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_orientation( ori );
+ if (_orientation != ori) {
+ 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_orientation( ori );
+ }
}
}
unsigned int source = sample->get_source();
alSourcefv( source, AL_POSITION, sample->get_position());
- alSourcefv( source, AL_DIRECTION, sample->get_direction() );
+ alSourcefv( source, AL_DIRECTION, sample->get_orientation() );
alSourcefv( source, AL_VELOCITY, sample->get_velocity() );
testForALError("position and orientation");
#if defined(__APPLE__)
# include <OpenAL/al.h>
+#elif defined(_WIN32)
+# include <al.h>
#else
# include <AL/al.h>
#endif
protected:
SGSoundMgr *_smgr;
+ string _refname;
bool _active;
private:
float _volume;
+ bool _tied_to_listener;
+
SGVec3d _position;
+ SGVec3f _velocity;
SGVec3f _orientation;
- bool _tied_to_listener;
sample_map _samples;
bool testForALError(string s);
bool testForError(void *p, string s);
- string _refname;
-
void update_sample_config( SGSoundSample *sound );
};
_absolute_pos(SGVec3d::zeros().data()),
_relative_pos(SGVec3f::zeros().data()),
_base_pos(SGVec3d::zeros().data()),
+ _orientation(SGVec3f::zeros().data()),
_direction(SGVec3f::zeros().data()),
_velocity(SGVec3f::zeros().data()),
_sample_name(""),
_absolute_pos(SGVec3d::zeros().data()),
_relative_pos(SGVec3f::zeros().data()),
_base_pos(SGVec3d::zeros().data()),
+ _orientation(SGVec3f::zeros().data()),
_direction(SGVec3f::zeros().data()),
_velocity(SGVec3f::zeros().data()),
_format(AL_FORMAT_MONO8),
_absolute_pos(SGVec3d::zeros().data()),
_relative_pos(SGVec3f::zeros().data()),
_base_pos(SGVec3d::zeros().data()),
+ _orientation(SGVec3f::zeros().data()),
_direction(SGVec3f::zeros().data()),
_velocity(SGVec3f::zeros().data()),
_data(data),
SGSoundSample::~SGSoundSample() {
}
+float *SGSoundSample::get_orientation() {
+#if 0
+ SGQuatf quat = SGQuatf::fromAngleAxis(_orientation);
+ SGVec3f orient = quat.transform(_direction);
+ return orient.data();
+#else
+ return _orientation.data();
+#endif
+}
+
void SGSoundSample::set_base_position( SGVec3d pos ) {
_base_pos = pos;
update_absolute_position();
_changed = true;
}
-void SGSoundSample::set_orientation( SGVec3f dir ) {
+void SGSoundSample::set_orientation( SGVec3f ori ) {
+ _orientation = ori;
+ update_absolute_position();
+ _changed = true;
+}
+
+void SGSoundSample::set_direction( SGVec3f dir ) {
_direction = dir;
update_absolute_position();
_changed = true;
}
void SGSoundSample::update_absolute_position() {
- SGQuatf orient = SGQuatf::fromAngleAxis(_direction);
+#if 0
+ SGQuatf orient = SGQuatf::fromAngleAxis(_orientation);
SGVec3f modified_relative_pos = orient.transform(_relative_pos);
_absolute_pos = _base_pos + toVec3d(modified_relative_pos);
+#else
+ _absolute_pos = _base_pos;
+#endif
}
SGVec3d _base_pos; // base position
// The orientation of the sound (direction and cut-off angles)
- SGVec3f _direction;
+ SGVec3f _orientation; // base orientation
+ SGVec3f _direction; // orientation offset
// Velocity of the source sound.
SGVec3f _velocity;
* Set the orientation of the sound source, both for direction
* and audio cut-off angles.
*/
- void set_orientation( SGVec3f dir );
+ void set_orientation( SGVec3f ori );
+
+ /**
+ * Set the relative direction of the sound source, both for direction
+ * and audio cut-off angles.
+ */
+ void set_direction( SGVec3f dir );
/**
* Define the audio cone parameters for directional audio
* Get the orientation of the sound source, the inner or outer angle
* or outer gain.
*/
- inline float *get_orientation() { return _direction.data(); }
- inline float *get_direction() { return _direction.data(); }
+ float *get_orientation();
+
inline float get_innerangle() { return _inner_angle; }
inline float get_outerangle() { return _outer_angle; }
inline float get_outergain() { return _outer_gain; }
_volume(0.0),
_device(NULL),
_context(NULL),
- _listener_pos(SGVec3d::zeros().data()),
- _listener_vel(SGVec3f::zeros().data()),
+ _position(SGVec3d::zeros().data()),
+ _velocity(SGVec3f::zeros().data()),
_devname(NULL)
{
#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
_context = context;
_working = true;
- _listener_ori[0] = 0.0; _listener_ori[1] = 0.0; _listener_ori[2] = -1.0;
- _listener_ori[3] = 0.0; _listener_ori[4] = 1.0; _listener_ori[5] = 0.0;
+ _orientation[0] = 0.0; _orientation[1] = 0.0; _orientation[2] = -1.0;
+ _orientation[3] = 0.0; _orientation[4] = 1.0; _orientation[5] = 0.0;
alListenerf( AL_GAIN, 0.2f );
- alListenerfv( AL_POSITION, toVec3f(_listener_pos).data() );
- alListenerfv( AL_ORIENTATION, _listener_ori );
- alListenerfv( AL_VELOCITY, _listener_vel.data() );
+ alListenerfv( AL_POSITION, toVec3f(_position).data() );
+ alListenerfv( AL_ORIENTATION, _orientation );
+ alListenerfv( AL_VELOCITY, _velocity.data() );
- alDopplerFactor(1.0);
+ alDopplerFactor(0.5);
alDopplerVelocity(340.3); // speed of sound in meters per second.
if ( alIsExtensionPresent((const ALchar*)"EXT_exponent_distance") ) {
if (_changed) {
alListenerf( AL_GAIN, _volume );
- alListenerfv( AL_VELOCITY, _listener_vel.data() );
- alListenerfv( AL_ORIENTATION, _listener_ori );
- alListenerfv( AL_POSITION, toVec3f(_listener_pos).data() );
+ alListenerfv( AL_VELOCITY, _velocity.data() );
+ alListenerfv( AL_ORIENTATION, _orientation );
+ alListenerfv( AL_POSITION, toVec3f(_position).data() );
// alDopplerVelocity(340.3); // TODO: altitude dependent
testForALError("update");
_changed = false;
_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 )
+{
+ SGVec3d sgv_up = ori.rotate(SGVec3d::e2());
+ SGVec3d sgv_at = ori.rotate(SGVec3d::e3());
+ _orientation[0] = sgv_at[0];
+ _orientation[1] = sgv_at[1];
+ _orientation[2] = sgv_at[2];
+ _orientation[3] = sgv_up[0];
+ _orientation[4] = sgv_up[1];
+ _orientation[5] = sgv_up[2];
+ _changed = true;
+}
+
// Get an unused source id
//
// The Sound Manager should keep track of the sources in use, the distance
}
-/**
- * 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 )
-{
- SGVec3d sgv_up = ori.rotate(SGVec3d::e3());
- SGVec3d sgv_at = ori.rotate(SGVec3d::e2());
- for (int i=0; i<3; i++) {
- _listener_ori[i] = sgv_at[i];
- _listener_ori[i+3] = sgv_up[i];
- }
- _changed = true;
-}
-
-
bool SGSoundMgr::testForError(void *p, string s)
{
if (p == NULL) {
# include <OpenAL/al.h>
# include <OpenAL/alc.h>
# include <OpenAL/alut.h>
+#elif defined(_WIN32)
+# include <al.h>
+# include <alc.h>
+# include <AL/alut.h>
#else
# include <AL/al.h>
# include <AL/alc.h>
/**
* set the position of the listener (in opengl coordinates)
*/
- inline void set_position( SGVec3d pos ) {
- _listener_pos = pos;
- _changed = true;
+ void set_position( SGVec3d pos ) {
+ if (_position != pos) {
+ _position = pos;
+ _changed = true;
+ }
}
- inline double *get_position() { return _listener_pos.data(); }
- inline SGVec3d get_position_vec() { return _listener_pos; };
+ inline double *get_position() { return _position.data(); }
+ inline SGVec3d get_position_vec() { return _position; };
/**
* set the velocity of the listener (in opengl coordinates)
*/
- inline void set_velocity( SGVec3f vel ) {
- _listener_vel = vel;
- _changed = true;
+ void set_velocity( SGVec3f vel ) {
+ if (_velocity != vel) {
+ _velocity = vel;
+ _changed = true;
+ }
}
- inline SGVec3f get_velocity() { return _listener_vel; }
+ inline SGVec3f get_velocity() { return _velocity; }
/**
* set the orientation of the listener (in opengl coordinates)
void set_orientation( SGQuatd ori );
inline SGVec3f get_direction() {
- return SGVec3f(_listener_ori[0], _listener_ori[1], _listener_ori[2]);
+ return SGVec3f(_orientation[0], _orientation[1], _orientation[2]);
}
enum {
ALCcontext *_context;
// Position of the listener.
- SGVec3d _listener_pos;
+ SGVec3d _position;
// Velocity of the listener.
- SGVec3f _listener_vel;
+ SGVec3f _velocity;
// Orientation of the listener.
// first 3 elements are "at" vector, second 3 are "up" vector
- ALfloat _listener_ori[6];
+ ALfloat _orientation[6];
sample_group_map _sample_groups;
buffer_map _buffers;
// Relative position
//
SGVec3f offset_pos = SGVec3f::zeros();
- SGPropertyNode_ptr pos = node->getChild("position");
- if ( pos != NULL ) {
- offset_pos[0] = pos->getDoubleValue("x", 0.0);
- offset_pos[1] = -pos->getDoubleValue("y", 0.0);
- offset_pos[2] = pos->getDoubleValue("z", 0.0);
+ SGPropertyNode_ptr prop = node->getChild("position");
+ if ( prop != NULL ) {
+ offset_pos[0] = prop->getDoubleValue("x", 0.0);
+ offset_pos[1] = -prop->getDoubleValue("y", 0.0);
+ offset_pos[2] = prop->getDoubleValue("z", 0.0);
}
//
float inner, outer, outer_gain;
inner = outer = 360.0;
outer_gain = 0.0;
- pos = node->getChild("orientation");
- if ( pos != NULL ) {
- dir[0] = pos->getDoubleValue("x", 0.0);
- dir[1] = -pos->getDoubleValue("y", 0.0);
- dir[2] = pos->getDoubleValue("z", 0.0);
- inner = pos->getDoubleValue("inner-angle", 360.0);
- outer = pos->getDoubleValue("outer-angle", 360.0);
- outer_gain = pos->getDoubleValue("outer-gain", 0.0);
+ prop = node->getChild("orientation");
+ if ( prop != NULL ) {
+ dir[0] = prop->getDoubleValue("x", 0.0);
+ dir[1] = -prop->getDoubleValue("y", 0.0);
+ dir[2] = prop->getDoubleValue("z", 0.0);
+ inner = prop->getDoubleValue("inner-angle", 360.0);
+ outer = prop->getDoubleValue("outer-angle", 360.0);
+ outer_gain = prop->getDoubleValue("outer-gain", 0.0);
}
//
// Initialize the sample
//
_sgrp = sgrp;
- if ( (_sample = _sgrp->find(_name)) == NULL ) {
- // FIXME: Does it make sense to overwrite a previous entry's
- // configuration just because a new entry has the same name?
- // Note that we can't match on identical "path" because we the
- // new entry could be at a different location with different
- // configuration so we need a new sample which creates a new
- // "alSource". The semantics of what is going on here seems
- // confused and needs to be thought through more carefully.
- _sample = new SGSoundSample( path.c_str(),
- node->getStringValue("path", "") );
- _sgrp->add( _sample, _name );
- }
-
+ _sample = new SGSoundSample( path.c_str(), node->getStringValue("path", ""));
_sample->set_relative_position( offset_pos );
- _sample->set_orientation( dir );
+ _sample->set_direction( dir );
_sample->set_audio_cone(inner, outer, outer_gain);
_sample->set_reference_dist( reference_dist );
_sample->set_max_dist( max_dist );
_sample->set_volume(v);
_sample->set_pitch(p);
+ _sgrp->add( _sample, _name );
}
void