X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fsound%2Fsample_openal.cxx;h=4be9d8113f02c9c068afd605e3c7926d58bded95;hb=6ccad915373fe367f8d63eb69282146054d0a401;hp=d2242d3ceb72dba4f57a9231a9fc46f5ad1bcfe3;hpb=7d239fe4ac7af88c7a4c11c6355adae18fbf9171;p=simgear.git diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index d2242d3c..4be9d811 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample_openal.cxx @@ -1,8 +1,10 @@ -// sample.cxx -- Sound sample encapsulation class +// sample_openal.cxx -- Audio sample encapsulation class // // Written by Curtis Olson, started April 2004. +// Modified to match the new SoundSystem by Erik Hofman, October 2009 // -// Copyright (C) 2004 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 2004 Curtis L. Olson - http://www.flightgear.org/~curt +// Copyright (C) 2009 Erik Hofman // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -15,26 +17,23 @@ // General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ - -#if defined( __APPLE__ ) -# define AL_ILLEGAL_ENUM AL_INVALID_ENUM -# define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION -# include -# include -#else -# include -# include +#ifdef HAVE_CONFIG_H +# include #endif +#include // rand() + #include -#include #include +#include +#include +#include "soundmgr_openal.hxx" #include "sample_openal.hxx" @@ -42,175 +41,191 @@ // SGSoundSample // - -static void print_openal_error( ALuint error ) { - if ( error == AL_INVALID_NAME ) { - SG_LOG( SG_GENERAL, SG_ALERT, "AL_INVALID_NAME" ); - } else if ( error == AL_ILLEGAL_ENUM ) { - SG_LOG( SG_GENERAL, SG_ALERT, "AL_ILLEGAL_ENUM" ); - } else if ( error == AL_INVALID_VALUE ) { - SG_LOG( SG_GENERAL, SG_ALERT, "AL_INVALID_VALUE" ); - } else if ( error == AL_ILLEGAL_COMMAND ) { - SG_LOG( SG_GENERAL, SG_ALERT, "AL_ILLEGAL_COMMAND" ); - } else if ( error == AL_OUT_OF_MEMORY ) { - SG_LOG( SG_GENERAL, SG_ALERT, "AL_OUT_OF_MEMORY" ); - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Unhandled error code = " << error ); - } +// empty constructor +SGSoundSample::SGSoundSample() : + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGGeod::fromDeg(0,0)), + _refname(random_string()), + _data(NULL), + _format(AL_FORMAT_MONO8), + _size(0), + _freq(0), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _inner_angle(360.0), + _outer_angle(360.0), + _outer_gain(0.0), + _pitch(1.0), + _volume(1.0), + _master_volume(1.0), + _reference_dist(500.0), + _max_dist(3000.0), + _loop(AL_FALSE), + _playing(false), + _changed(true), + _static_changed(true), + _is_file(false) +{ } - // constructor -SGSoundSample::SGSoundSample( const char *path, const char *file, - bool cleanup ) : - data(NULL), - pitch(1.0), - volume(1.0), - reference_dist(500.0), - max_dist(3000.), - loop(AL_FALSE) +SGSoundSample::SGSoundSample( const char *path, const char *file ) : + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGGeod::fromDeg(0,0)), + _refname(file), + _data(NULL), + _format(AL_FORMAT_MONO8), + _size(0), + _freq(0), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _inner_angle(360.0), + _outer_angle(360.0), + _outer_gain(0.0), + _pitch(1.0), + _volume(1.0), + _master_volume(1.0), + _reference_dist(500.0), + _max_dist(3000.0), + _loop(AL_FALSE), + _playing(false), + _changed(true), + _static_changed(true), + _is_file(true) { SGPath samplepath( path ); if ( strlen(file) ) { samplepath.append( file ); } - - sample_name = samplepath.str(); - - SG_LOG( SG_GENERAL, SG_DEBUG, "From file sounds sample = " - << samplepath.str() ); - - ALuint error; - - source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0; - source_vel[0] = 0.0; source_vel[1] = 0.0; source_vel[2] = 0.0; - - // clear errors from elsewhere? - alGetError(); - - // create an OpenAL buffer handle - alGenBuffers(1, &buffer); - error = alGetError(); - if ( error != AL_NO_ERROR ) { - print_openal_error( error ); - throw sg_exception("Failed to gen OpenAL buffer."); - } - - // Load the sample file -#if defined (__APPLE__) - alutLoadWAVFile( (ALbyte *)samplepath.c_str(), - &format, &data, &size, &freq ); -#else - alutLoadWAVFile( (ALbyte *)samplepath.c_str(), - &format, &data, &size, &freq, &loop ); -#endif - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to load wav file."); - } - - // Copy data to the internal OpenAL buffer - alBufferData( buffer, format, data, size, freq ); - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to buffer data."); - } - - if ( cleanup ) { - alutUnloadWAV( format, data, size, freq ); - data = NULL; - } - - // Bind buffer with a source. - alGenSources(1, &source); - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to gen source."); - } - - alSourcei( source, AL_BUFFER, buffer ); - alSourcef( source, AL_PITCH, pitch ); - alSourcef( source, AL_GAIN, volume ); - alSourcefv( source, AL_POSITION, source_pos ); - 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 ); + _refname = samplepath.str(); } - // constructor -SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) : - data(NULL), - pitch(1.0), - volume(1.0), - reference_dist(500.0), - max_dist(3000.), - loop(AL_FALSE) +SGSoundSample::SGSoundSample( const unsigned char** data, + int len, int freq, int format ) : + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGGeod::fromDeg(0,0)), + _refname(random_string()), + _format(format), + _size(len), + _freq(freq), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _inner_angle(360.0), + _outer_angle(360.0), + _outer_gain(0.0), + _pitch(1.0), + _volume(1.0), + _master_volume(1.0), + _reference_dist(500.0), + _max_dist(3000.0), + _loop(AL_FALSE), + _playing(false), + _changed(true), + _static_changed(true), + _is_file(false) { SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" ); + _data = (unsigned char*)*data; *data = NULL; +} - sample_name = "unknown, generated from data"; - - source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0; - source_vel[0] = 0.0; source_vel[1] = 0.0; source_vel[2] = 0.0; - - // Load wav data into a buffer. - alGenBuffers(1, &buffer); - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to gen buffer." ); - return; - } - - format = AL_FORMAT_MONO8; - size = len; - data = _data; - freq = _freq; - - alBufferData( buffer, format, data, size, freq ); - - // Bind buffer with a source. - alGenSources(1, &source); - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to gen source."); - } - - alSourcei( source, AL_BUFFER, buffer ); - alSourcef( source, AL_PITCH, pitch ); - alSourcef( source, AL_GAIN, volume ); - alSourcefv( source, AL_POSITION, source_pos ); - 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 ); +// constructor +SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) : + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGGeod::fromDeg(0,0)), + _refname(random_string()), + _format(format), + _size(len), + _freq(freq), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _inner_angle(360.0), + _outer_angle(360.0), + _outer_gain(0.0), + _pitch(1.0), + _volume(1.0), + _master_volume(1.0), + _reference_dist(500.0), + _max_dist(3000.0), + _loop(AL_FALSE), + _playing(false), + _changed(true), + _static_changed(true), + _is_file(false) +{ + SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" ); + _data = (unsigned char*)*data; *data = NULL; } // destructor SGSoundSample::~SGSoundSample() { - SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" ); - if ( data != NULL ) { - free(data); - } - alDeleteSources(1, &source); - alDeleteBuffers(1, &buffer); + if (_data) free(_data); } +void SGSoundSample::update_pos_and_orientation() { + // The rotation rotating from the earth centerd frame to + // the horizontal local frame + SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos); + + // Compute the sounds orientation and position + // wrt the earth centered frame - that is global coorinates + SGQuatd sc2body = hlOr*_orientation; -// play the sample -void SGSoundSample::play( bool _loop ) { - loop = _loop; - - // make sure sound isn't already playing - alSourceStop( source ); + // This is rotates the x-forward, y-right, z-down coordinate system where + // simulation runs into the OpenGL camera system with x-right, y-up, z-back. + SGQuatd q(-0.5, -0.5, 0.5, 0.5); - alSourcei( source, AL_LOOPING, loop ); - alSourcePlay( source ); + // The cartesian position of the sounds base location + SGVec3d position = SGVec3d::fromGeod(_base_pos); + + _absolute_pos = position; +#if 0 + if ( _relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { + _absolute_pos += (sc2body*q).backTransform(_relative_pos); + } +#endif + if ( _direction[0] || _direction[1] || _direction[2] ) { + _orivec = toVec3f( (sc2body*q).backTransform(_direction) ); + } } +string SGSoundSample::random_string() { + static const char *r = "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + string rstr = "System generated name: "; + for (int i=0; i<10; i++) { + rstr.push_back( r[rand() % strlen(r)] ); + } -// stop playing the sample -void SGSoundSample::stop() { - alSourceStop( source ); + return rstr; } +