+ if (playing) {
+ alSourceStop( source );
+ alDeleteSources(1, &source);
+ source = 0;
+ print_openal_error("stop (alDeleteSources)");
+ }
+ playing = false;
+}
+
+// Generate sound source
+bool
+SGSoundSample::bind_source() {
+
+ if ( playing ) {
+ return true;
+ }
+
+ // Bind buffer with a source.
+ alGetError();
+ alGenSources(1, &source);
+ if ( print_openal_error("bind_source (alGenSources)") ) {
+ // No biggy, better luck next time.
+ SG_LOG( SG_GENERAL, SG_ALERT, "Failed to generate audio source.");
+ // SG_LOG( SG_GENERAL, SG_ALERT, "Please update your sound driver and try again.");
+ return false;
+ }
+
+ alSourcei( source, AL_BUFFER, buffer );
+ alSourcef( source, AL_PITCH, pitch );
+ alSourcef( source, AL_GAIN, volume );
+ alSourcefv( source, AL_POSITION, source_pos );
+ alSourcefv( source, AL_DIRECTION, direction );
+ alSourcef( source, AL_CONE_INNER_ANGLE, inner );
+ alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
+ alSourcef( source, AL_CONE_OUTER_GAIN, outergain);
+ alSourcefv( source, AL_VELOCITY, source_vel );
+ alSourcei( source, AL_LOOPING, loop );
+
+ alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
+ alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
+ alSourcef( source, AL_MAX_DISTANCE, max_dist );
+
+ print_openal_error("bind_sources return");
+
+ return true;
+}
+
+void
+SGSoundSample::set_pitch( double p ) {
+ // clamp in the range of 0.01 to 2.0
+ if ( p < 0.01 ) { p = 0.01; }
+ if ( p > 2.0 ) { p = 2.0; }
+ pitch = p;
+ if (playing) {
+ alSourcef( source, AL_PITCH, pitch );
+ print_openal_error("set_pitch");
+ }
+}
+
+void
+SGSoundSample::set_volume( double v ) {
+ volume = v;
+ if (playing) {
+ alSourcef( source, AL_GAIN, volume );
+ print_openal_error("set_volume");
+ }
+}
+
+
+bool
+SGSoundSample::is_playing( ) {
+ if (playing) {
+ ALint result;
+ alGetSourcei( source, AL_SOURCE_STATE, &result );
+ if ( alGetError() != AL_NO_ERROR) {
+ SG_LOG( SG_GENERAL, SG_ALERT,
+ "Oops AL error in sample is_playing(): " << sample_name );
+ }
+ return (result == AL_PLAYING) ;
+ } else
+ return false;
+}
+
+void
+SGSoundSample::set_source_pos( ALfloat *pos ) {
+ source_pos[0] = pos[0];
+ source_pos[1] = pos[1];
+ source_pos[2] = pos[2];
+
+ if (playing) {
+ sgVec3 final_pos;
+ sgAddVec3( final_pos, source_pos, offset_pos );
+
+ alSourcefv( source, AL_POSITION, final_pos );
+ }
+}
+
+void
+SGSoundSample::set_offset_pos( ALfloat *pos ) {
+ offset_pos[0] = pos[0];
+ offset_pos[1] = pos[1];
+ offset_pos[2] = pos[2];
+
+ if (playing) {
+ sgVec3 final_pos;
+ sgAddVec3( final_pos, source_pos, offset_pos );
+
+ alSourcefv( source, AL_POSITION, final_pos );
+ }
+}
+
+void
+SGSoundSample::set_orientation( ALfloat *dir, ALfloat inner_angle,
+ ALfloat outer_angle,
+ ALfloat outer_gain)
+{
+ inner = inner_angle;
+ outer = outer_angle;
+ outergain = outer_gain;
+ if (playing) {
+ alSourcefv( source, AL_DIRECTION, dir);
+ alSourcef( source, AL_CONE_INNER_ANGLE, inner );
+ alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
+ alSourcef( source, AL_CONE_OUTER_GAIN, outergain );
+ }
+}
+
+void
+SGSoundSample::set_source_vel( ALfloat *vel ) {
+ source_vel[0] = vel[0];
+ source_vel[1] = vel[1];
+ source_vel[2] = vel[2];
+ if (playing) {
+ alSourcefv( source, AL_VELOCITY, source_vel );
+ }
+}
+
+void
+SGSoundSample::set_reference_dist( ALfloat dist ) {
+ reference_dist = dist;
+ if (playing) {
+ alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
+ }
+}
+
+
+void
+SGSoundSample::set_max_dist( ALfloat dist ) {
+ max_dist = dist;
+ if (playing) {
+ alSourcef( source, AL_MAX_DISTANCE, max_dist );
+ }