X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fsound%2Fsample_openal.cxx;h=95a6077559822deda6ff7e0f99a67cfc02eba758;hb=a62f11c5509f8d7b2a4c3b587c0e7af8d4f5a39b;hp=6d3739dca3f52c2eb06fd86029f085aab05f07a2;hpb=edd92caba146a9accdb1ad930b31bdebe3103ca8;p=simgear.git diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample_openal.cxx index 6d3739dc..95a60775 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,194 +17,248 @@ // 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(), free() +#include +#include + #include -#include #include +#include +#include +#include "soundmgr_openal.hxx" #include "sample_openal.hxx" +#include "soundmgr_openal_private.hxx" + +#define AL_FALSE 0 +using std::string; // // 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() : + _format(AL_FORMAT_MONO8), + _size(0), + _freq(0), + _changed(true), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGVec3d::zeros()), + _rotation(SGQuatd::zeros()), + _refname(random_string()), + _data(NULL), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _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), + _static_changed(true), + _out_of_range(false), + _is_file(false), + _use_pos_props(false) +{ + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } - // constructor -SGSoundSample::SGSoundSample( const char *path, const char *file, - bool cleanup ) : - data(NULL), - pitch(1.0), - volume(1.0), - loop(AL_FALSE) +SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) : + _format(AL_FORMAT_MONO8), + _size(0), + _freq(0), + _changed(true), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGVec3d::zeros()), + _rotation(SGQuatd::zeros()), + _refname(file), + _data(NULL), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _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), + _static_changed(true), + _out_of_range(false), + _is_file(true), + _use_pos_props(false) { - 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, 500.0f ); - alSourcef( source, AL_MAX_DISTANCE, 3000.0f ); + SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir); + _refname = p.str(); + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; } - // constructor -SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) : - data(NULL), - pitch(1.0), - volume(1.0), - loop(AL_FALSE) +SGSoundSample::SGSoundSample( const unsigned char** data, + int len, int freq, int format ) : + _format(format), + _size(len), + _freq(freq), + _changed(true), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGVec3d::zeros()), + _rotation(SGQuatd::zeros()), + _refname(random_string()), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _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), + _static_changed(true), + _out_of_range(false), + _is_file(false), + _use_pos_props(false) { - SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" ); - - sample_name = "unknown, generated from data"; + SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); + _data = (unsigned char*)*data; *data = NULL; + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 0; +} - 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; +// constructor +SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) : + _format(format), + _size(len), + _freq(freq), + _changed(true), + _valid_source(false), + _source(SGSoundMgr::NO_SOURCE), + _absolute_pos(SGVec3d::zeros()), + _relative_pos(SGVec3d::zeros()), + _direction(SGVec3d::zeros()), + _velocity(SGVec3f::zeros()), + _orientation(SGQuatd::zeros()), + _orivec(SGVec3f::zeros()), + _base_pos(SGVec3d::zeros()), + _rotation(SGQuatd::zeros()), + _refname(random_string()), + _valid_buffer(false), + _buffer(SGSoundMgr::NO_BUFFER), + _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), + _static_changed(true), + _out_of_range(false), + _is_file(false), + _use_pos_props(false) +{ + SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); + _data = (unsigned char*)*data; *data = NULL; + _pos_prop[0] = 0; + _pos_prop[1] = 0; + _pos_prop[2] = 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; +// destructor +SGSoundSample::~SGSoundSample() { + if ( _data != NULL ) free(_data); +} - alBufferData( buffer, format, data, size, freq ); +void SGSoundSample::update_pos_and_orientation() { - // Bind buffer with a source. - alGenSources(1, &source); - if (alGetError() != AL_NO_ERROR) { - throw sg_exception("Failed to gen source."); + if (_use_pos_props) { + if (_pos_prop[0]) _absolute_pos[0] = _pos_prop[0]->getDoubleValue(); + if (_pos_prop[1]) _absolute_pos[1] = _pos_prop[1]->getDoubleValue(); + if (_pos_prop[2]) _absolute_pos[2] = _pos_prop[2]->getDoubleValue(); + } + else { + _absolute_pos = _base_pos; + if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { + _absolute_pos += _rotation.rotate( _relative_pos ); + } } - 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 ); -} - - -// destructor -SGSoundSample::~SGSoundSample() { - SG_LOG( SG_GENERAL, SG_INFO, "Deleting a sample" ); - if ( data != NULL ) { - free(data); + _orivec = SGVec3f::zeros(); + if ( _direction[0] || _direction[1] || _direction[2] ) { + _orivec = toVec3f( _rotation.rotate( _direction ) ); } - alDeleteSources(1, &source); - alDeleteBuffers(1, &buffer); } +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)] ); + } -// play the sample -void SGSoundSample::play( bool _loop ) { - loop = _loop; - - // make sure sound isn't already playing - alSourceStop( source ); - - alSourcei( source, AL_LOOPING, loop ); - alSourcePlay( source ); + return rstr; } +SGPath SGSoundSample::file_path() const +{ + if (!_is_file) { + return SGPath(); + } + + return SGPath(_refname); +} -// stop playing the sample -void SGSoundSample::stop() { - alSourceStop( source ); +void SGSoundSample::free_data() +{ + if ( _data != NULL ) free( _data ); _data = NULL; }