Erik Hofman
1. Remove the dependency on alut which (on certein platforms) might pose some restrictuons on commercial use. 2. Create a sound source just prior to playing the sound and destroy it again when the sound has stopped. This should greatly reduce the error reports from Windows users.
This commit is contained in:
+186
-62
@@ -43,20 +43,24 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
static void print_openal_error( ALuint error ) {
|
static bool print_openal_error(const string &s = "unknown") {
|
||||||
if ( error == AL_INVALID_NAME ) {
|
ALuint error = alGetError();
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "AL_INVALID_NAME" );
|
if ( error == AL_NO_ERROR ) {
|
||||||
|
return false;
|
||||||
|
} else if ( error == AL_INVALID_NAME ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_ALERT, "OpenAL error (AL_INVALID_NAME): " << s );
|
||||||
} else if ( error == AL_ILLEGAL_ENUM ) {
|
} else if ( error == AL_ILLEGAL_ENUM ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "AL_ILLEGAL_ENUM" );
|
SG_LOG( SG_GENERAL, SG_ALERT, "OpenAL error (AL_ILLEGAL_ENUM): " << s );
|
||||||
} else if ( error == AL_INVALID_VALUE ) {
|
} else if ( error == AL_INVALID_VALUE ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "AL_INVALID_VALUE" );
|
SG_LOG( SG_GENERAL, SG_ALERT, "OpenAL error (AL_INVALID_VALUE): " << s );
|
||||||
} else if ( error == AL_ILLEGAL_COMMAND ) {
|
} else if ( error == AL_ILLEGAL_COMMAND ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "AL_ILLEGAL_COMMAND" );
|
SG_LOG( SG_GENERAL, SG_ALERT, "OpenAL error (AL_ILLEGAL_COMMAND): " << s );
|
||||||
} else if ( error == AL_OUT_OF_MEMORY ) {
|
} else if ( error == AL_OUT_OF_MEMORY ) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "AL_OUT_OF_MEMORY" );
|
SG_LOG( SG_GENERAL, SG_ALERT, "OpenAL error (AL_OUT_OF_MEMORY): " << s );
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Unhandled error code = " << error );
|
SG_LOG( SG_GENERAL, SG_ALERT, "Unhandled error code = " << error );
|
||||||
}
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -64,11 +68,14 @@ static void print_openal_error( ALuint error ) {
|
|||||||
SGSoundSample::SGSoundSample( const char *path, const char *file,
|
SGSoundSample::SGSoundSample( const char *path, const char *file,
|
||||||
bool cleanup ) :
|
bool cleanup ) :
|
||||||
data(NULL),
|
data(NULL),
|
||||||
|
buffer(0),
|
||||||
|
source(0),
|
||||||
pitch(1.0),
|
pitch(1.0),
|
||||||
volume(1.0),
|
volume(1.0),
|
||||||
reference_dist(500.0),
|
reference_dist(500.0),
|
||||||
max_dist(3000.),
|
max_dist(3000.),
|
||||||
loop(AL_FALSE)
|
loop(AL_FALSE),
|
||||||
|
playing(false)
|
||||||
{
|
{
|
||||||
SGPath samplepath( path );
|
SGPath samplepath( path );
|
||||||
if ( strlen(file) ) {
|
if ( strlen(file) ) {
|
||||||
@@ -91,9 +98,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
|
|||||||
|
|
||||||
// create an OpenAL buffer handle
|
// create an OpenAL buffer handle
|
||||||
alGenBuffers(1, &buffer);
|
alGenBuffers(1, &buffer);
|
||||||
ALuint error = alGetError();
|
if ( print_openal_error("constructor (alGenBuffers)") ) {
|
||||||
if ( error != AL_NO_ERROR ) {
|
|
||||||
print_openal_error( error );
|
|
||||||
throw sg_exception("Failed to gen OpenAL buffer.");
|
throw sg_exception("Failed to gen OpenAL buffer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,13 +110,13 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
|
|||||||
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
|
alutLoadWAVFile( (ALbyte *)samplepath.c_str(),
|
||||||
&format, &data, &size, &freq, &loop );
|
&format, &data, &size, &freq, &loop );
|
||||||
#endif
|
#endif
|
||||||
if (alGetError() != AL_NO_ERROR) {
|
if ( print_openal_error("constructor (alutLoadWAVFile)") ) {
|
||||||
throw sg_exception("Failed to load wav file.");
|
throw sg_exception("Failed to load wav file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy data to the internal OpenAL buffer
|
// Copy data to the internal OpenAL buffer
|
||||||
alBufferData( buffer, format, data, size, freq );
|
alBufferData( buffer, format, data, size, freq );
|
||||||
if (alGetError() != AL_NO_ERROR) {
|
if ( print_openal_error("constructor (alBufferData)") ) {
|
||||||
throw sg_exception("Failed to buffer data.");
|
throw sg_exception("Failed to buffer data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,26 +125,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
|
|||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind buffer with a source.
|
print_openal_error("constructor return");
|
||||||
alGenSources(1, &source);
|
|
||||||
if (alGetError() != AL_NO_ERROR) {
|
|
||||||
throw sg_exception("Failed to gen source.\nPlease update your sound driver and try again.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -147,11 +133,14 @@ SGSoundSample::SGSoundSample( const char *path, const char *file,
|
|||||||
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
||||||
bool cleanup) :
|
bool cleanup) :
|
||||||
data(NULL),
|
data(NULL),
|
||||||
|
buffer(0),
|
||||||
|
source(0),
|
||||||
pitch(1.0),
|
pitch(1.0),
|
||||||
volume(1.0),
|
volume(1.0),
|
||||||
reference_dist(500.0),
|
reference_dist(500.0),
|
||||||
max_dist(3000.),
|
max_dist(3000.),
|
||||||
loop(AL_FALSE)
|
loop(AL_FALSE),
|
||||||
|
playing(false)
|
||||||
{
|
{
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" );
|
SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" );
|
||||||
|
|
||||||
@@ -168,11 +157,8 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
|||||||
|
|
||||||
// Load wav data into a buffer.
|
// Load wav data into a buffer.
|
||||||
alGenBuffers(1, &buffer);
|
alGenBuffers(1, &buffer);
|
||||||
ALuint error = alGetError();
|
if ( print_openal_error("constructor (alGenBuffers)") ) {
|
||||||
if ( error != AL_NO_ERROR ) {
|
|
||||||
print_openal_error( error );
|
|
||||||
throw sg_exception("Failed to gen buffer." );
|
throw sg_exception("Failed to gen buffer." );
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
format = AL_FORMAT_MONO8;
|
format = AL_FORMAT_MONO8;
|
||||||
@@ -181,7 +167,7 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
|||||||
freq = _freq;
|
freq = _freq;
|
||||||
|
|
||||||
alBufferData( buffer, format, data, size, freq );
|
alBufferData( buffer, format, data, size, freq );
|
||||||
if (alGetError() != AL_NO_ERROR) {
|
if ( print_openal_error("constructor (alBufferData)") ) {
|
||||||
throw sg_exception("Failed to buffer data.");
|
throw sg_exception("Failed to buffer data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,10 +176,63 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
|||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_openal_error("constructor return");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
SGSoundSample::~SGSoundSample() {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" );
|
||||||
|
alDeleteBuffers(1, &buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// play the sample
|
||||||
|
void SGSoundSample::play( bool _loop ) {
|
||||||
|
|
||||||
|
if ( source ) {
|
||||||
|
alSourceStop( source );
|
||||||
|
}
|
||||||
|
|
||||||
|
playing = bind_source();
|
||||||
|
if ( playing ) {
|
||||||
|
loop = _loop;
|
||||||
|
|
||||||
|
alSourcei( source, AL_LOOPING, loop );
|
||||||
|
alSourcePlay( source );
|
||||||
|
|
||||||
|
print_openal_error("play (alSourcePlay)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// stop playing the sample
|
||||||
|
void SGSoundSample::stop() {
|
||||||
|
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.
|
// Bind buffer with a source.
|
||||||
|
alGetError();
|
||||||
alGenSources(1, &source);
|
alGenSources(1, &source);
|
||||||
if (alGetError() != AL_NO_ERROR) {
|
if ( print_openal_error("bind_source (alGenSources)") ) {
|
||||||
throw sg_exception("Failed to gen source.\nPlease update your sound driver and try again.");
|
// 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 );
|
alSourcei( source, AL_BUFFER, buffer );
|
||||||
@@ -203,37 +242,122 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq,
|
|||||||
alSourcefv( source, AL_DIRECTION, direction );
|
alSourcefv( source, AL_DIRECTION, direction );
|
||||||
alSourcef( source, AL_CONE_INNER_ANGLE, inner );
|
alSourcef( source, AL_CONE_INNER_ANGLE, inner );
|
||||||
alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
|
alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
|
||||||
alSourcef( source, AL_CONE_OUTER_GAIN, outergain );
|
alSourcef( source, AL_CONE_OUTER_GAIN, outergain);
|
||||||
alSourcefv( source, AL_VELOCITY, source_vel );
|
alSourcefv( source, AL_VELOCITY, source_vel );
|
||||||
alSourcei( source, AL_LOOPING, loop );
|
alSourcei( source, AL_LOOPING, loop );
|
||||||
|
|
||||||
alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
|
alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||||
alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
|
alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
|
||||||
alSourcef( source, AL_MAX_DISTANCE, max_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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
bool
|
||||||
SGSoundSample::~SGSoundSample() {
|
SGSoundSample::is_playing( ) {
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" );
|
if (playing) {
|
||||||
alDeleteSources(1, &source);
|
ALint result;
|
||||||
alDeleteBuffers(1, &buffer);
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// play the sample
|
void
|
||||||
void SGSoundSample::play( bool _loop ) {
|
SGSoundSample::set_max_dist( ALfloat dist ) {
|
||||||
loop = _loop;
|
max_dist = dist;
|
||||||
|
if (playing) {
|
||||||
// make sure sound isn't already playing
|
alSourcef( source, AL_MAX_DISTANCE, max_dist );
|
||||||
alSourceStop( source );
|
}
|
||||||
|
|
||||||
alSourcei( source, AL_LOOPING, loop );
|
|
||||||
alSourcePlay( source );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// stop playing the sample
|
|
||||||
void SGSoundSample::stop() {
|
|
||||||
alSourceStop( source );
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ private:
|
|||||||
double max_dist;
|
double max_dist;
|
||||||
ALboolean loop;
|
ALboolean loop;
|
||||||
|
|
||||||
|
bool playing;
|
||||||
|
bool bind_source();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -149,15 +151,7 @@ public:
|
|||||||
* Test if a sample is curretnly playing.
|
* Test if a sample is curretnly playing.
|
||||||
* @return true if is is playing, false otherwise.
|
* @return true if is is playing, false otherwise.
|
||||||
*/
|
*/
|
||||||
inline bool is_playing( ) {
|
bool is_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) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current pitch setting of this sample.
|
* Get the current pitch setting of this sample.
|
||||||
@@ -167,18 +161,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Set the pitch of this sample.
|
* Set the pitch of this sample.
|
||||||
*/
|
*/
|
||||||
inline void set_pitch( double p ) {
|
void 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;
|
|
||||||
alSourcef( source, AL_PITCH, pitch );
|
|
||||||
if ( alGetError() != AL_NO_ERROR) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
||||||
"Oops AL error in sample set_pitch()! " << p
|
|
||||||
<< " for " << sample_name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current volume setting of this sample.
|
* Get the current volume setting of this sample.
|
||||||
@@ -188,15 +171,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Set the volume of this sample.
|
* Set the volume of this sample.
|
||||||
*/
|
*/
|
||||||
inline void set_volume( double v ) {
|
void set_volume( double v );
|
||||||
volume = v;
|
|
||||||
alSourcef( source, AL_GAIN, volume );
|
|
||||||
if ( alGetError() != AL_NO_ERROR) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
|
||||||
"Oops AL error in sample set_volume()! " << v
|
|
||||||
<< " for " << sample_name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size of the sounds sample
|
* Returns the size of the sounds sample
|
||||||
@@ -215,78 +190,40 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Set position of sound source (uses same coordinate system as opengl)
|
* Set position of sound source (uses same coordinate system as opengl)
|
||||||
*/
|
*/
|
||||||
inline void set_source_pos( ALfloat *pos ) {
|
void set_source_pos( ALfloat *pos );
|
||||||
source_pos[0] = pos[0];
|
|
||||||
source_pos[1] = pos[1];
|
|
||||||
source_pos[2] = pos[2];
|
|
||||||
|
|
||||||
sgVec3 final_pos;
|
|
||||||
sgAddVec3( final_pos, source_pos, offset_pos );
|
|
||||||
|
|
||||||
alSourcefv( source, AL_POSITION, final_pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set "constant" offset position of sound source (uses same
|
* Set "constant" offset position of sound source (uses same
|
||||||
* coordinate system as opengl)
|
* coordinate system as opengl)
|
||||||
*/
|
*/
|
||||||
inline void set_offset_pos( ALfloat *pos ) {
|
void set_offset_pos( ALfloat *pos );
|
||||||
offset_pos[0] = pos[0];
|
|
||||||
offset_pos[1] = pos[1];
|
|
||||||
offset_pos[2] = pos[2];
|
|
||||||
|
|
||||||
sgVec3 final_pos;
|
|
||||||
sgAddVec3( final_pos, source_pos, offset_pos );
|
|
||||||
|
|
||||||
alSourcefv( source, AL_POSITION, final_pos );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the orientation of the sound source, both for direction
|
* Set the orientation of the sound source, both for direction
|
||||||
* and audio cut-off angles.
|
* and audio cut-off angles.
|
||||||
*/
|
*/
|
||||||
inline void set_orientation( ALfloat *dir, ALfloat inner_angle=360.0,
|
void set_orientation( ALfloat *dir, ALfloat inner_angle=360.0,
|
||||||
ALfloat outer_angle=360.0,
|
ALfloat outer_angle=360.0,
|
||||||
ALfloat outer_gain=0.0)
|
ALfloat outer_gain=0.0);
|
||||||
{
|
|
||||||
inner = inner_angle;
|
|
||||||
outer = outer_angle;
|
|
||||||
outergain = outer_gain;
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set velocity of sound source (uses same coordinate system as opengl)
|
* Set velocity of sound source (uses same coordinate system as opengl)
|
||||||
*/
|
*/
|
||||||
inline void set_source_vel( ALfloat *vel ) {
|
void set_source_vel( ALfloat *vel );
|
||||||
source_vel[0] = vel[0];
|
|
||||||
source_vel[1] = vel[1];
|
|
||||||
source_vel[2] = vel[2];
|
|
||||||
alSourcefv( source, AL_VELOCITY, source_vel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set reference distance of sound (the distance where the gain
|
* Set reference distance of sound (the distance where the gain
|
||||||
* will be half.)
|
* will be half.)
|
||||||
*/
|
*/
|
||||||
inline void set_reference_dist( ALfloat dist ) {
|
void set_reference_dist( ALfloat dist );
|
||||||
reference_dist = dist;
|
|
||||||
alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set maximume distance of sound (the distance where the sound is
|
* Set maximume distance of sound (the distance where the sound is
|
||||||
* no longer audible.
|
* no longer audible.
|
||||||
*/
|
*/
|
||||||
inline void set_max_dist( ALfloat dist ) {
|
void set_max_dist( ALfloat dist );
|
||||||
max_dist = dist;
|
|
||||||
alSourcef( source, AL_MAX_DISTANCE, max_dist );
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,9 @@
|
|||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
# include <OpenAL/al.h>
|
# include <OpenAL/al.h>
|
||||||
# include <OpenAL/alut.h>
|
|
||||||
# include <OpenAL/alc.h>
|
# include <OpenAL/alc.h>
|
||||||
#else
|
#else
|
||||||
# include <AL/al.h>
|
# include <AL/al.h>
|
||||||
# include <AL/alut.h>
|
|
||||||
# include <AL/alc.h>
|
# include <AL/alc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -71,11 +69,13 @@ SGSoundMgr::SGSoundMgr() {
|
|||||||
SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
|
SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
|
||||||
|
|
||||||
// initialize OpenAL
|
// initialize OpenAL
|
||||||
alutInit( 0, NULL );
|
if ( (dev = alcOpenDevice( NULL )) != NULL) {
|
||||||
atexit(alutExit);
|
context = alcCreateContext( dev, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
if ( alGetError() == AL_NO_ERROR) {
|
if ( (dev != NULL) && (context != NULL) ) {
|
||||||
working = true;
|
working = true;
|
||||||
|
alcMakeContextCurrent( context );
|
||||||
} else {
|
} else {
|
||||||
working = false;
|
working = false;
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
|
SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
|
||||||
@@ -115,6 +115,7 @@ SGSoundMgr::SGSoundMgr() {
|
|||||||
|
|
||||||
SGSoundMgr::~SGSoundMgr() {
|
SGSoundMgr::~SGSoundMgr() {
|
||||||
|
|
||||||
|
alcDestroyContext( context );
|
||||||
//
|
//
|
||||||
// Remove the samples from the sample manager.
|
// Remove the samples from the sample manager.
|
||||||
//
|
//
|
||||||
@@ -162,8 +163,7 @@ void SGSoundMgr::update( double dt ) {
|
|||||||
void
|
void
|
||||||
SGSoundMgr::pause ()
|
SGSoundMgr::pause ()
|
||||||
{
|
{
|
||||||
ALCcontext *pCurContext = alcGetCurrentContext();
|
alcSuspendContext( context );
|
||||||
alcSuspendContext( pCurContext );
|
|
||||||
if ( alGetError() != AL_NO_ERROR) {
|
if ( alGetError() != AL_NO_ERROR) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Oops AL error after soundmgr pause()!" );
|
"Oops AL error after soundmgr pause()!" );
|
||||||
@@ -174,8 +174,7 @@ SGSoundMgr::pause ()
|
|||||||
void
|
void
|
||||||
SGSoundMgr::resume ()
|
SGSoundMgr::resume ()
|
||||||
{
|
{
|
||||||
ALCcontext *pCurContext = alcGetCurrentContext();
|
alcProcessContext( context );
|
||||||
alcProcessContext( pCurContext );
|
|
||||||
if ( alGetError() != AL_NO_ERROR) {
|
if ( alGetError() != AL_NO_ERROR) {
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Oops AL error after soundmgr resume()!" );
|
"Oops AL error after soundmgr resume()!" );
|
||||||
|
|||||||
@@ -44,8 +44,10 @@
|
|||||||
|
|
||||||
#if defined( __APPLE__ )
|
#if defined( __APPLE__ )
|
||||||
# include <OpenAL/al.h>
|
# include <OpenAL/al.h>
|
||||||
|
# include <OpenAL/alc.h>
|
||||||
#else
|
#else
|
||||||
# include <AL/al.h>
|
# include <AL/al.h>
|
||||||
|
# include <AL/alc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sample_openal.hxx"
|
#include "sample_openal.hxx"
|
||||||
@@ -65,6 +67,9 @@ typedef sample_map::const_iterator const_sample_map_iterator;
|
|||||||
class SGSoundMgr
|
class SGSoundMgr
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ALCdevice *dev;
|
||||||
|
ALCcontext *context;
|
||||||
|
|
||||||
// Position of the listener.
|
// Position of the listener.
|
||||||
ALfloat listener_pos[3];
|
ALfloat listener_pos[3];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user