From 86f462933d0d7130e4e688183976620ed2ddb5ae Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 4 Oct 2009 13:52:53 +0000 Subject: [PATCH 01/62] Initial commit of the new sound system, expect more updates to follow --- src/ATCDCL/AIPlane.cxx | 31 ++--- src/ATCDCL/AIPlane.hxx | 6 +- src/ATCDCL/ATC.cxx | 71 +++++------ src/ATCDCL/ATC.hxx | 52 ++++---- src/ATCDCL/ATCVoice.cxx | 59 +++++---- src/Aircraft/aircraft.cxx | 4 +- src/Environment/environment_ctrl.hxx | 1 + src/Environment/fgclouds.cxx | 7 +- src/Environment/fgclouds.hxx | 5 +- src/Instrumentation/adf.cxx | 27 ++-- src/Instrumentation/adf.hxx | 6 +- src/Instrumentation/kr_87.cxx | 21 ++-- src/Instrumentation/kr_87.hxx | 3 + src/Instrumentation/marker_beacon.cxx | 46 +++---- src/Instrumentation/marker_beacon.hxx | 3 + src/Instrumentation/mk_viii.cxx | 36 ++---- src/Instrumentation/mk_viii.hxx | 37 +++--- src/Instrumentation/navradio.cxx | 43 ++++--- src/Instrumentation/navradio.hxx | 3 + src/Main/fg_commands.cxx | 9 +- src/Main/fg_init.cxx | 28 ++--- src/Main/fg_props.cxx | 10 +- src/Main/globals.cxx | 3 - src/Main/globals.hxx | 9 +- src/Main/main.cxx | 18 ++- src/Main/viewmgr.cxx | 12 ++ src/Model/acmodel.cxx | 64 ++++++++-- src/Model/acmodel.hxx | 14 ++- src/Sound/beacon.cxx | 14 +-- src/Sound/fg_fx.cxx | 173 +++++--------------------- src/Sound/fg_fx.hxx | 20 +-- src/Sound/morse.cxx | 10 -- 32 files changed, 406 insertions(+), 439 deletions(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 1c394d638..1db5820ec 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -47,12 +47,18 @@ FGAIPlane::FGAIPlane() { _trackSet = false; _tgtRoll = 0.0; _rollSuspended = false; + _sgr = 0; } FGAIPlane::~FGAIPlane() { } void FGAIPlane::Update(double dt) { + if (!_sgr) { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + if (smgr) _sgr = smgr->find("atc", true); + } + if(_pending) { if(tuned_station) { if(tuned_station->GetFreqClear()) { @@ -106,7 +112,7 @@ void FGAIPlane::Update(double dt) { // For now assume in range !!! // TODO - implement range checking // TODO - at the moment the volume is always set off comm1 - double volume = fgGetDouble("/instrumentation/comm[0]/volume"); + float volume = fgGetFloat("/instrumentation/comm[0]/volume"); Render(plane.callsign, volume, false); } } @@ -167,8 +173,9 @@ void FGAIPlane::ConditionalTransmit(double timeout, int callback_code) { } void FGAIPlane::ImmediateTransmit(int callback_code) { - // TODO - at the moment the volume is always set off comm1 - double volume = fgGetDouble("/instrumentation/comm[0]/volume"); + // TODO - at the moment the volume is always set off comm1 + float volume = fgGetFloat("/instrumentation/comm[0]/volume"); + Render(plane.callsign, volume, false); if(callback_code) { ProcessCallback(callback_code); @@ -183,24 +190,20 @@ void FGAIPlane::ProcessCallback(int code) { // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager // The repeating flag indicates whether the message should be repeated continuously or played once. -void FGAIPlane::Render(const string& refname, const double volume, bool repeating) { +void FGAIPlane::Render(const string& refname, const float volume, bool repeating) { fgSetString("/sim/messages/ai-plane", pending_transmission.c_str()); #ifdef ENABLE_AUDIO_SUPPORT voice = (voiceOK && fgGetBool("/sim/sound/voice")); if(voice) { string buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice); - if(voice) { + if(voice && (volume > 0.05)) { SGSoundSample* simple = - new SGSoundSample((unsigned char*)buf.c_str(), buf.length(), 8000, AL_FORMAT_MONO8 ); + new SGSoundSample((unsigned char*)buf.c_str(), buf.length(), 8000 ); // TODO - at the moment the volume can't be changed // after the transmission has started. simple->set_volume(volume); - globals->get_soundmgr()->add(simple, refname); - if(repeating) { - globals->get_soundmgr()->play_looped(refname); - } else { - globals->get_soundmgr()->play_once(refname); - } + _sgr->add(simple, refname); + _sgr->play(refname, repeating); } } #endif // ENABLE_AUDIO_SUPPORT @@ -221,8 +224,8 @@ void FGAIPlane::NoRender(const string& refname) { if(playing) { if(voice) { #ifdef ENABLE_AUDIO_SUPPORT - globals->get_soundmgr()->stop(refname); - globals->get_soundmgr()->remove(refname); + _sgr->stop(refname); + _sgr->remove(refname); #endif } playing = false; diff --git a/src/ATCDCL/AIPlane.hxx b/src/ATCDCL/AIPlane.hxx index e1f581c6c..aba6e7b7e 100644 --- a/src/ATCDCL/AIPlane.hxx +++ b/src/ATCDCL/AIPlane.hxx @@ -24,6 +24,8 @@ #include "AIEntity.hxx" #include "ATC.hxx" +class SGSampleGroup; + enum PatternLeg { TAKEOFF_ROLL, CLIMBOUT, @@ -140,7 +142,7 @@ private: // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager // The repeating flag indicates whether the message should be repeated continuously or played once. - void Render(const string& refname, const double volume, bool repeating); + void Render(const string& refname, const float volume, bool repeating); // Cease rendering a transmission. // Requires the sound manager refname if audio, else "". @@ -157,6 +159,8 @@ private: bool _trackSet; // Set true if tgtTrack is to be followed double _tgtRoll; bool _rollSuspended; // Set true when a derived class has suspended AIPlane's roll control + + SGSampleGroup *_sgr; }; #endif // _FG_AI_PLANE_HXX diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 193b82457..ed62bad03 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -35,7 +35,8 @@ FGATC::FGATC() : - _voiceOK(false), + _voiceOK(false), + _sgr(NULL), freqClear(true), receiving(false), respond(false), @@ -203,7 +204,7 @@ int FGATC::RemovePlane() { } void FGATC::SetData(ATCData* d) { - _type = d->type; + _type = d->type; _geod = d->geod; _cart = d->cart; range = d->range; @@ -216,41 +217,41 @@ void FGATC::SetData(ATCData* d) { // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager // The repeating flag indicates whether the message should be repeated continuously or played once. -void FGATC::Render(string& msg, const double volume, - const string& refname, const bool repeating) { +void FGATC::Render(string& msg, const float volume, + const string& refname, const bool repeating) { if (repeating) fgSetString("/sim/messages/atis", msg.c_str()); else fgSetString("/sim/messages/atc", msg.c_str()); - #ifdef ENABLE_AUDIO_SUPPORT +#ifdef ENABLE_AUDIO_SUPPORT _voice = (_voiceOK && fgGetBool("/sim/sound/voice")); if(_voice) { - string buf = _vPtr->WriteMessage((char*)msg.c_str(), _voice); - if(_voice) { - NoRender(refname); - try { + string buf = _vPtr->WriteMessage((char*)msg.c_str(), _voice); + if(_voice && (volume > 0.05)) { + NoRender(refname); + try { // >>> Beware: must pass a (new) object to the (add) method, // >>> because the (remove) method is going to do a (delete) // >>> whether that's what you want or not. - SGSoundSample *simple = - new SGSoundSample((unsigned char*) buf.c_str(), - buf.length(), 8000, AL_FORMAT_MONO8); - // TODO - at the moment the volume can't be changed - // after the transmission has started. - simple->set_volume(volume); - globals->get_soundmgr()->add(simple, refname); - if(repeating) { - globals->get_soundmgr()->play_looped(refname); - } else { - globals->get_soundmgr()->play_once(refname); - } - } catch ( sg_io_exception &e ) { - SG_LOG(SG_GENERAL, SG_ALERT, e.getFormattedMessage()); + SGSoundSample *simple = + new SGSoundSample((unsigned char*) buf.c_str(), buf.length(), 8000); + // TODO - at the moment the volume can't be changed + // after the transmission has started. + if (!_sgr) { + SGSoundMgr *smgr; + smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("atc", true); + } + simple->set_volume(volume); + _sgr->add(simple, refname); + _sgr->play(refname, repeating); + } catch ( sg_io_exception &e ) { + SG_LOG(SG_GENERAL, SG_ALERT, e.getFormattedMessage()); + } } - } } - #endif // ENABLE_AUDIO_SUPPORT +#endif // ENABLE_AUDIO_SUPPORT if(!_voice) { // first rip the underscores and the pause hints out of the string - these are for the convienience of the voice parser for(unsigned int i = 0; i < msg.length(); ++i) { @@ -268,8 +269,8 @@ void FGATC::NoRender(const string& refname) { if(_playing) { if(_voice) { #ifdef ENABLE_AUDIO_SUPPORT - globals->get_soundmgr()->stop(refname); - globals->get_soundmgr()->remove(refname); + _sgr->stop(refname); + _sgr->remove(refname); #endif } _playing = false; @@ -283,14 +284,14 @@ string FGATC::GenText(const string& m, int c) { ostream& operator << (ostream& os, atc_type atc) { switch(atc) { - case(AWOS): return(os << "AWOS"); - case(ATIS): return(os << "ATIS"); - case(GROUND): return(os << "GROUND"); - case(TOWER): return(os << "TOWER"); + case(AWOS): return(os << "AWOS"); + case(ATIS): return(os << "ATIS"); + case(GROUND): return(os << "GROUND"); + case(TOWER): return(os << "TOWER"); case(APPROACH): return(os << "APPROACH"); case(DEPARTURE): return(os << "DEPARTURE"); - case(ENROUTE): return(os << "ENROUTE"); - case(INVALID): return(os << "INVALID"); + case(ENROUTE): return(os << "ENROUTE"); + case(INVALID): return(os << "INVALID"); } return(os << "ERROR - Unknown switch in atc_type operator << "); } @@ -325,7 +326,7 @@ std::istream& operator >> ( std::istream& fin, ATCData& a ) return fin >> skipeol; } - double lat, lon, elev; + double lat, lon, elev; fin >> lat >> lon >> elev >> f >> a.range >> a.ident; a.geod = SGGeod::fromDegM(lon, lat, elev); @@ -349,7 +350,7 @@ std::istream& operator >> ( std::istream& fin, ATCData& a ) // cout << a.ident << endl; // generate cartesian coordinates - a.cart = SGVec3d::fromGeod(a.geod); + a.cart = SGVec3d::fromGeod(a.geod); return fin >> skipeol; } diff --git a/src/ATCDCL/ATC.hxx b/src/ATCDCL/ATC.hxx index adb62264e..8b05d6ca0 100644 --- a/src/ATCDCL/ATC.hxx +++ b/src/ATCDCL/ATC.hxx @@ -33,6 +33,8 @@ #include "ATCVoice.hxx" +class SGSampleGroup; + // Convert a frequency in MHz to tens of kHz // so we can use it e.g. as an index into commlist_freq // @@ -76,7 +78,7 @@ enum atc_type { APPROACH, DEPARTURE, ENROUTE, - INVALID /* must be last element; see ATC_NUM_TYPES */ + INVALID /* must be last element; see ATC_NUM_TYPES */ }; const int ATC_NUM_TYPES = 1 + INVALID; @@ -84,8 +86,8 @@ const int ATC_NUM_TYPES = 1 + INVALID; // DCL - new experimental ATC data store struct ATCData { atc_type type; - SGGeod geod; - SGVec3d cart; + SGGeod geod; + SGVec3d cart; unsigned short int freq; unsigned short int range; std::string ident; @@ -114,7 +116,7 @@ public: FGATC(); virtual ~FGATC(); - virtual void Init()=0; + virtual void Init()=0; // Run the internal calculations // Derived classes should call this method from their own Update methods if they @@ -176,15 +178,15 @@ protected: // Outputs the transmission either on screen or as audio depending on user preference // The refname is a string to identify this sample to the sound manager // The repeating flag indicates whether the message should be repeated continuously or played once. - void Render(std::string& msg, const double volume = 1.0, - const std::string& refname = "", bool repeating = false); + void Render(std::string& msg, const float volume = 1.0, + const std::string& refname = "", bool repeating = false); // Cease rendering all transmission from this station. // Requires the sound manager refname if audio, else "". void NoRender(const std::string& refname); // Transmit a message when channel becomes free of other dialog - void Transmit(int callback_code = 0); + void Transmit(int callback_code = 0); // Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit void ConditionalTransmit(double timeout, int callback_code = 0); @@ -197,44 +199,46 @@ protected: SGGeod _geod; SGVec3d _cart; int freq; - std::map<std::string,int> active_on; + std::map<std::string,int> active_on; int range; - std::string ident; // Code of the airport its at. - std::string name; // Name transmitted in the broadcast. + std::string ident; // Code of the airport its at. + std::string name; // Name transmitted in the broadcast. // Rendering related stuff - bool _voice; // Flag - true if we are using voice - bool _playing; // Indicates a message in progress - bool _voiceOK; // Flag - true if at least one voice has loaded OK + bool _voice; // Flag - true if we are using voice + bool _playing; // Indicates a message in progress + bool _voiceOK; // Flag - true if at least one voice has loaded OK FGATCVoice* _vPtr; + SGSampleGroup *_sgr; // default sample group; + - bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog - bool receiving; // Flag to indicate we are receiving a transmission + bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog + bool receiving; // Flag to indicate we are receiving a transmission - double responseTime; // Time to take from end of request transmission to beginning of response - // The idea is that this will be slightly random. + double responseTime; // Time to take from end of request transmission to beginning of response + // The idea is that this will be slightly random. - bool respond; // Flag to indicate now is the time to respond - ie set following the count down of the response timer. + bool respond; // Flag to indicate now is the time to respond - ie set following the count down of the response timer. std::string responseID; // ID of the plane to respond to - bool runResponseCounter; // Flag to indicate the response counter should be run - double responseCounter; // counter to implement the above + bool runResponseCounter; // Flag to indicate the response counter should be run + double responseCounter; // counter to implement the above // Derived classes only need monitor this flag, and use the response ID, as long as they call FGATC::Update(...) bool _runReleaseCounter; // A timer for releasing the frequency after giving the message enough time to display - bool responseReqd; // Flag to indicate we should be responding to a request/report + bool responseReqd; // Flag to indicate we should be responding to a request/report double _releaseTime; double _releaseCounter; atc_type _type; - bool _display; // Flag to indicate whether we should be outputting to the ATC display. - std::string pending_transmission; // derived classes set this string before calling Transmit(...) + bool _display; // Flag to indicate whether we should be outputting to the ATC display. + std::string pending_transmission; // derived classes set this string before calling Transmit(...) private: // Transmission timing stuff. double _timeout; - bool _pending; + bool _pending; int _callback_code; // A callback code to be notified and processed by the derived classes // A value of zero indicates no callback required diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx index 46ab81df7..023dde22c 100644 --- a/src/ATCDCL/ATCVoice.cxx +++ b/src/ATCDCL/ATCVoice.cxx @@ -33,11 +33,11 @@ #include <boost/shared_array.hpp> +#include <simgear/sound/soundmgr_openal.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/debug/logstream.hxx> #include <simgear/misc/sgstream.hxx> #include <simgear/math/sg_random.h> -#include <simgear/sound/sample_openal.hxx> #include <Main/globals.hxx> @@ -56,29 +56,28 @@ FGATCVoice::FGATCVoice() { FGATCVoice::~FGATCVoice() { if (rawSoundData) - free( rawSoundData ); + free( rawSoundData ); delete SoundData; } // Load the two voice files - one containing the raw sound data (.wav) and one containing the word positions (.vce). // Return true if successful. bool FGATCVoice::LoadVoice(const string& voice) { - // FIXME CLO: disabled to try to see if this is causing problemcs - // return false; - std::ifstream fin; SGPath path = globals->get_fg_root(); + string file = voice + ".wav"; path.append( "ATC" ); - - string file = voice + ".wav"; + path.append( file ); - SGSoundSample SoundData; - rawSoundData = (char *)SoundData.load_file(path.c_str(), file.c_str()); - rawDataSize = SoundData.get_size(); + string full_path = path.str(); + int format, freq; + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + void *data; + smgr->load(full_path, &data, &format, &rawDataSize, &freq); + rawSoundData = (char*)data; #ifdef VOICE_TEST - ALenum fmt = SoundData.get_format(); - cout << "ATCVoice: format: " << fmt + cout << "ATCVoice: format: " << format << " size: " << rawDataSize << endl; #endif path = globals->get_fg_root(); @@ -113,12 +112,12 @@ bool FGATCVoice::LoadVoice(const string& voice) { wd.offset = wrdOffset; wd.length = wrdLength; wordMap[wrdstr] = wd; - string ws2 = wrdstr; - for(string::iterator p = ws2.begin(); p != ws2.end(); p++){ - *p = tolower(*p); - if (*p == '-') *p = '_'; - } - if (wrdstr != ws2) wordMap[ws2] = wd; + string ws2 = wrdstr; + for(string::iterator p = ws2.begin(); p != ws2.end(); p++){ + *p = tolower(*p); + if (*p == '-') *p = '_'; + } + if (wrdstr != ws2) wordMap[ws2] = wd; //cout << wrd << "\t\t" << wrdOffset << "\t\t" << wrdLength << '\n'; //cout << i << '\n'; @@ -146,7 +145,7 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { // TODO - at the moment we're effectively taking 3 passes through the data. // There is no need for this - 2 should be sufficient - we can probably ditch the tokenList. size_t n1 = 1+strlen(message); - boost::shared_array<char> msg(new char[n1]); + boost::shared_array<char> msg(new char[n1]); strncpy(msg.get(), message, n1); // strtok requires a non-const char* char* token; int numWords = 0; @@ -154,19 +153,19 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { char* context; token = strtok_r(msg.get(), delimiters, &context); while(token != NULL) { - for (char *t = token; *t; t++) { - *t = tolower(*t); // canonicalize the case, to - if (*t == '-') *t = '_'; // match what's in the index - } + for (char *t = token; *t; t++) { + *t = tolower(*t); // canonicalize the case, to + if (*t == '-') *t = '_'; // match what's in the index + } tokenList.push_back(token); ++numWords; SG_LOG(SG_ATC, SG_DEBUG, "voice synth: token: '" - << token << "'"); + << token << "'"); token = strtok_r(NULL, delimiters, &context); } vector<WordData> wdptr; - wdptr.reserve(numWords); + wdptr.reserve(numWords); unsigned int cumLength = 0; tokenListItr = tokenList.begin(); @@ -174,21 +173,21 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { if(wordMap.find(*tokenListItr) == wordMap.end()) { // Oh dear - the token isn't in the sound file SG_LOG(SG_ATC, SG_ALERT, "voice synth: word '" - << *tokenListItr << "' not found"); + << *tokenListItr << "' not found"); } else { - wdptr.push_back(wordMap[*tokenListItr]); - cumLength += wdptr.back().length; + wdptr.push_back(wordMap[*tokenListItr]); + cumLength += wdptr.back().length; } ++tokenListItr; } const size_t word = wdptr.size(); - + // Check for no tokens found else slScheduler can be crashed if(!word) { dataOK = false; return ""; } - boost::shared_array<char> tmpbuf(new char[cumLength]); + boost::shared_array<char> tmpbuf(new char[cumLength]); unsigned int bufpos = 0; for(int i=0; i<word; ++i) { /* diff --git a/src/Aircraft/aircraft.cxx b/src/Aircraft/aircraft.cxx index 60b5eb311..ba760a33b 100644 --- a/src/Aircraft/aircraft.cxx +++ b/src/Aircraft/aircraft.cxx @@ -34,6 +34,7 @@ #include <simgear/misc/sg_path.hxx> #include <simgear/structure/commands.hxx> #include <simgear/structure/exception.hxx> +#include <simgear/sound/soundmgr_openal.hxx> #include <Main/globals.hxx> #include <Main/fg_init.hxx> @@ -226,12 +227,9 @@ fgLoadAircraft (const SGPropertyNode * arg) t = fgInitTime(); globals->set_time_params( t ); - // Reinitialize some subsystems - // globals->get_viewmgr()->reinit(); globals->get_controls()->reset_all(); globals->get_aircraft_model()->reinit(); - globals->get_subsystem("fx")->reinit(); globals->get_subsystem("xml-autopilot")->reinit(); fgReInitSubsystems(); diff --git a/src/Environment/environment_ctrl.hxx b/src/Environment/environment_ctrl.hxx index 76b6aab20..0ecf8db8b 100644 --- a/src/Environment/environment_ctrl.hxx +++ b/src/Environment/environment_ctrl.hxx @@ -40,6 +40,7 @@ // forward decls class SGPropertyNode; +class SGSampleGroup; class FGMetar; /** diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 867798af4..a4264bc58 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -68,9 +68,10 @@ void FGClouds::init(void) { snd_lightning = new SGSoundSample(globals->get_fg_root().c_str(), "Sounds/thunder.wav"); snd_lightning->set_max_dist(7000.0f); snd_lightning->set_reference_dist(3000.0f); - SGSoundMgr *soundMgr = globals->get_soundmgr(); - soundMgr->add( snd_lightning, "thunder" ); - sgEnviro.set_soundMgr( soundMgr ); + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSampleGroup *sgr = smgr->find("weather", true); + sgr->add( snd_lightning, "thunder" ); + sgEnviro.set_sampleGroup( sgr ); } } diff --git a/src/Environment/fgclouds.hxx b/src/Environment/fgclouds.hxx index 797b55247..fd7ca885a 100644 --- a/src/Environment/fgclouds.hxx +++ b/src/Environment/fgclouds.hxx @@ -34,10 +34,11 @@ using std::string; -class SGNewCloud; +class SGSampleGroup; class SGCloudField; +class SGNewCloud; class FGMetar; -class FGEnvironmentCtrl; +//class FGEnvironmentCtrl; class FGClouds { diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx index 053812a0d..d2ac69145 100644 --- a/src/Instrumentation/adf.cxx +++ b/src/Instrumentation/adf.cxx @@ -69,7 +69,8 @@ ADF::ADF (SGPropertyNode *node ) _transmitter_range_nm(0), _ident_count(0), _last_ident_time(0), - _last_volume(-1) + _last_volume(-1), + _sgr(0) { } @@ -101,6 +102,9 @@ ADF::init () _ident_node = node->getChild("ident", 0, true); _ident_audible_node = node->getChild("ident-audible", 0, true); + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("avionics", true); + morse.init(); std::ostringstream temp; @@ -156,6 +160,7 @@ ADF::update (double delta_time_sec) double range_nm = adjust_range(_transmitter_pos.getElevationFt(), altitude_m * SG_METER_TO_FEET, _transmitter_range_nm); + if (distance_nm <= range_nm) { double bearing, az2, s; @@ -171,9 +176,9 @@ ADF::update (double delta_time_sec) set_bearing(delta_time_sec, bearing); // adf ident sound - double volume; + float volume; if ( _ident_audible_node->getBoolValue() ) - volume = _volume_node->getDoubleValue(); + volume = _volume_node->getFloatValue(); else volume = 0.0; @@ -181,7 +186,7 @@ ADF::update (double delta_time_sec) _last_volume = volume; SGSoundSample *sound; - sound = globals->get_soundmgr()->find( _adf_ident ); + sound = _sgr->find( _adf_ident ); if ( sound != NULL ) sound->set_volume( volume ); else @@ -195,8 +200,8 @@ ADF::update (double delta_time_sec) } if ( _ident_count < 4 ) { - if ( !globals->get_soundmgr()->is_playing(_adf_ident) ) { - globals->get_soundmgr()->play_once( _adf_ident ); + if ( !_sgr->is_playing(_adf_ident) && (volume > 0.05) ) { + _sgr->play_once( _adf_ident ); ++_ident_count; } } @@ -204,7 +209,7 @@ ADF::update (double delta_time_sec) _in_range_node->setBoolValue(false); set_bearing(delta_time_sec, 90); _ident_node->setStringValue(""); - globals->get_soundmgr()->stop( _adf_ident ); + _sgr->stop( _adf_ident ); } } @@ -234,16 +239,16 @@ ADF::search (double frequency_khz, double longitude_rad, _last_ident = ident; _ident_node->setStringValue(ident.c_str()); - if ( globals->get_soundmgr()->exists( _adf_ident ) ) { + if ( _sgr->exists( _adf_ident ) ) { // stop is required! -- remove alone wouldn't stop immediately - globals->get_soundmgr()->stop( _adf_ident ); - globals->get_soundmgr()->remove( _adf_ident ); + _sgr->stop( _adf_ident ); + _sgr->remove( _adf_ident ); } SGSoundSample *sound; sound = morse.make_ident( ident, LO_FREQUENCY ); sound->set_volume(_last_volume = 0); - globals->get_soundmgr()->add( sound, _adf_ident ); + _sgr->add( sound, _adf_ident ); int offset = (int)(sg_random() * 30.0); _ident_count = offset / 4; diff --git a/src/Instrumentation/adf.hxx b/src/Instrumentation/adf.hxx index 41d55671d..80de7d860 100644 --- a/src/Instrumentation/adf.hxx +++ b/src/Instrumentation/adf.hxx @@ -21,6 +21,8 @@ using std::string; +class SGSampleGroup; + /** * Model an ADF radio. * @@ -93,8 +95,10 @@ private: FGMorse morse; int _ident_count; time_t _last_ident_time; - double _last_volume; + float _last_volume; string _adf_ident; + + SGSampleGroup *_sgr; }; diff --git a/src/Instrumentation/kr_87.cxx b/src/Instrumentation/kr_87.cxx index 6683f8f93..eab9bf69b 100644 --- a/src/Instrumentation/kr_87.cxx +++ b/src/Instrumentation/kr_87.cxx @@ -105,7 +105,8 @@ FGKR_87::FGKR_87( SGPropertyNode *node ) : flight_timer(0.0), elapsed_timer(0.0), tmp_timer(0.0), - _time_before_search_sec(0) + _time_before_search_sec(0), + _sgr(NULL) { } @@ -116,6 +117,8 @@ FGKR_87::~FGKR_87() { void FGKR_87::init () { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("avionics", true); morse.init(); } @@ -463,7 +466,7 @@ void FGKR_87::update( double dt_sec ) { // otherwise turn it off if ( vol_btn >= 0.01 && audio_btn ) { SGSoundSample *sound; - sound = globals->get_soundmgr()->find( "adf-ident" ); + sound = _sgr->find( "adf-ident" ); if ( sound != NULL ) { if ( !adf_btn ) { sound->set_volume( vol_btn ); @@ -480,13 +483,13 @@ void FGKR_87::update( double dt_sec ) { } if ( play_count < 4 ) { // play ADF ident - if ( !globals->get_soundmgr()->is_playing("adf-ident") ) { - globals->get_soundmgr()->play_once( "adf-ident" ); + if ( !_sgr->is_playing("adf-ident") && (vol_btn > 0.05) ) { + _sgr->play_once( "adf-ident" ); ++play_count; } } } else { - globals->get_soundmgr()->stop( "adf-ident" ); + _sgr->stop( "adf-ident" ); } } } @@ -527,13 +530,13 @@ void FGKR_87::search() { effective_range = kludgeRange(stn_elev, pos.getElevationM(), range); xyz = adf->cart(); - if ( globals->get_soundmgr()->exists( "adf-ident" ) ) { - globals->get_soundmgr()->remove( "adf-ident" ); + if ( _sgr->exists( "adf-ident" ) ) { + _sgr->remove( "adf-ident" ); } SGSoundSample *sound; sound = morse.make_ident( trans_ident, LO_FREQUENCY ); sound->set_volume( 0.3 ); - globals->get_soundmgr()->add( sound, "adf-ident" ); + _sgr->add( sound, "adf-ident" ); int offset = (int)(sg_random() * 30.0); play_count = offset / 4; @@ -551,7 +554,7 @@ void FGKR_87::search() { valid = false; ident = ""; trans_ident = ""; - globals->get_soundmgr()->remove( "adf-ident" ); + _sgr->remove( "adf-ident" ); last_ident = ""; // cout << "not picking up adf. :-(" << endl; } diff --git a/src/Instrumentation/kr_87.hxx b/src/Instrumentation/kr_87.hxx index 0b57a8e5f..0653b06d9 100644 --- a/src/Instrumentation/kr_87.hxx +++ b/src/Instrumentation/kr_87.hxx @@ -34,6 +34,7 @@ #include <Navaids/navlist.hxx> #include <Sound/morse.hxx> +class SGSampleGroup; class FGKR_87 : public SGSubsystem { @@ -104,6 +105,8 @@ class FGKR_87 : public SGSubsystem // internal periodic station search timer double _time_before_search_sec; + SGSampleGroup *_sgr; + public: FGKR_87( SGPropertyNode *node ); diff --git a/src/Instrumentation/marker_beacon.cxx b/src/Instrumentation/marker_beacon.cxx index e1ca85e12..ccb8499e1 100644 --- a/src/Instrumentation/marker_beacon.cxx +++ b/src/Instrumentation/marker_beacon.cxx @@ -49,7 +49,8 @@ FGMarkerBeacon::FGMarkerBeacon(SGPropertyNode *node) : inner_blink(false), name("marker-beacon"), num(0), - _time_before_search_sec(0.0) + _time_before_search_sec(0.0), + _sgr(NULL) { SGPath path( globals->get_fg_root() ); SGPath term = path; @@ -116,6 +117,9 @@ FGMarkerBeacon::init () if (serviceable->getType() == simgear::props::NONE) serviceable->setBoolValue( true ); + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("avionics", true); + morse.init(); beacon.init(); blink.stamp(); @@ -300,9 +304,9 @@ void FGMarkerBeacon::search() if ( b == NULL || !inrange || !has_power() || !serviceable->getBoolValue() ) { // cout << "no marker" << endl; - globals->get_soundmgr()->stop( "outer-marker" ); - globals->get_soundmgr()->stop( "middle-marker" ); - globals->get_soundmgr()->stop( "inner-marker" ); + _sgr->stop( "outer-marker" ); + _sgr->stop( "middle-marker" ); + _sgr->stop( "inner-marker" ); } else { string current_sound_name; @@ -312,63 +316,63 @@ void FGMarkerBeacon::search() current_sound_name = "outer-marker"; // cout << "OUTER MARKER" << endl; if ( last_beacon != OUTER ) { - if ( ! globals->get_soundmgr()->exists( current_sound_name ) ) { + if ( ! _sgr->exists( current_sound_name ) ) { SGSoundSample *sound = beacon.get_outer(); if ( sound ) { - globals->get_soundmgr()->add( sound, current_sound_name ); + _sgr->add( sound, current_sound_name ); } } } if ( audio_btn->getBoolValue() ) { - if ( !globals->get_soundmgr()->is_playing(current_sound_name) ) { - globals->get_soundmgr()->play_looped( current_sound_name ); + if ( !_sgr->is_playing(current_sound_name) ) { + _sgr->play_looped( current_sound_name ); } } else { - globals->get_soundmgr()->stop( current_sound_name ); + _sgr->stop( current_sound_name ); } } else if ( beacon_type == MIDDLE ) { middle_marker = true; current_sound_name = "middle-marker"; // cout << "MIDDLE MARKER" << endl; if ( last_beacon != MIDDLE ) { - if ( ! globals->get_soundmgr()->exists( current_sound_name ) ) { + if ( ! _sgr->exists( current_sound_name ) ) { SGSoundSample *sound = beacon.get_middle(); if ( sound ) { - globals->get_soundmgr()->add( sound, current_sound_name ); + _sgr->add( sound, current_sound_name ); } } } if ( audio_btn->getBoolValue() ) { - if ( !globals->get_soundmgr()->is_playing(current_sound_name) ) { - globals->get_soundmgr()->play_looped( current_sound_name ); + if ( !_sgr->is_playing(current_sound_name) ) { + _sgr->play_looped( current_sound_name ); } } else { - globals->get_soundmgr()->stop( current_sound_name ); + _sgr->stop( current_sound_name ); } } else if ( beacon_type == INNER ) { inner_marker = true; current_sound_name = "inner-marker"; // cout << "INNER MARKER" << endl; if ( last_beacon != INNER ) { - if ( ! globals->get_soundmgr()->exists( current_sound_name ) ) { + if ( ! _sgr->exists( current_sound_name ) ) { SGSoundSample *sound = beacon.get_inner(); if ( sound ) { - globals->get_soundmgr()->add( sound, current_sound_name ); + _sgr->add( sound, current_sound_name ); } } } if ( audio_btn->getBoolValue() ) { - if ( !globals->get_soundmgr()->is_playing(current_sound_name) ) { - globals->get_soundmgr()->play_looped( current_sound_name ); + if ( !_sgr->is_playing(current_sound_name) ) { + _sgr->play_looped( current_sound_name ); } } else { - globals->get_soundmgr()->stop( current_sound_name ); + _sgr->stop( current_sound_name ); } } // cout << "VOLUME " << audio_vol->getDoubleValue() << endl; - SGSoundSample * mkr = globals->get_soundmgr()->find( current_sound_name ); + SGSoundSample * mkr = _sgr->find( current_sound_name ); if (mkr) - mkr->set_volume( audio_vol->getDoubleValue() ); + mkr->set_volume( audio_vol->getFloatValue() ); } if ( inrange ) { diff --git a/src/Instrumentation/marker_beacon.hxx b/src/Instrumentation/marker_beacon.hxx index cb82eea5c..774e37f81 100644 --- a/src/Instrumentation/marker_beacon.hxx +++ b/src/Instrumentation/marker_beacon.hxx @@ -35,6 +35,7 @@ #include <Sound/beacon.hxx> #include <Sound/morse.hxx> +class SGSampleGroup; class FGMarkerBeacon : public SGSubsystem { @@ -73,6 +74,8 @@ class FGMarkerBeacon : public SGSubsystem // internal periodic station search timer double _time_before_search_sec; + SGSampleGroup *_sgr; + public: enum fgMkrBeacType { diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index 64e187f6f..3cdc6e3ef 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2127,11 +2127,9 @@ MK_VIII::VoicePlayer::Speaker::update_configuration () SGSoundSample *sample = (*iter).second; sample->set_pitch(pitch); - sample->set_offset_pos(position); - sample->set_orientation(orientation, - inner_cone, - outer_cone, - outer_gain); + sample->set_base_position(position); // TODO: tie to listener pos + sample->set_orientation(orientation); + sample->set_audio_cone(inner_cone, outer_cone, outer_gain); sample->set_reference_dist(reference_dist); sample->set_max_dist(max_dist); } @@ -2172,7 +2170,7 @@ MK_VIII::VoicePlayer::Voice::stop (bool now) } void -MK_VIII::VoicePlayer::Voice::set_volume (double _volume) +MK_VIII::VoicePlayer::Voice::set_volume (float _volume) { volume = _volume; volume_changed(); @@ -2209,15 +2207,6 @@ MK_VIII::VoicePlayer::~VoicePlayer () for (iter1 = _voices.begin(); iter1 != _voices.end(); iter1++) delete *iter1; _voices.clear(); - -/* sound mgr already destroyed - samples already deleted - map<string, SGSoundSample *>::iterator iter2; - for (iter2 = samples.begin(); iter2 != samples.end(); iter2++) - { - bool status = globals->get_soundmgr()->remove((*iter2).first); - assert(status); - } -*/ samples.clear(); } @@ -2226,6 +2215,9 @@ MK_VIII::VoicePlayer::init () { #define STDPAUSE 0.75 // [SPEC] 6.4.4: "the standard 0.75 second delay" + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("avionics", true); + make_voice(&voices.application_data_base_failed, "application-data-base-failed"); make_voice(&voices.bank_angle, "bank-angle"); make_voice(&voices.bank_angle_bank_angle, "bank-angle", "bank-angle"); @@ -2270,13 +2262,7 @@ MK_VIII::VoicePlayer::get_sample (const char *name) std::ostringstream refname; refname << mk->name << "[" << mk->num << "]" << "/" << name; - SGSoundMgr *soundmgr = globals->get_soundmgr(); - if (soundmgr->is_working() == false) - { - return NULL; - } - - SGSoundSample *sample = soundmgr->find(refname.str()); + SGSoundSample *sample = _sgr->find(refname.str()); if (! sample) { SGPath sample_path(globals->get_fg_root()); @@ -2293,7 +2279,7 @@ MK_VIII::VoicePlayer::get_sample (const char *name) exit(1); } - soundmgr->add(sample, refname.str()); + _sgr->add(sample, refname.str()); samples[refname.str()] = sample; } @@ -2338,7 +2324,7 @@ MK_VIII::VoicePlayer::stop (unsigned int flags) } void -MK_VIII::VoicePlayer::set_volume (double _volume) +MK_VIII::VoicePlayer::set_volume (float _volume) { volume = _volume; if (voice) @@ -4130,7 +4116,7 @@ MK_VIII::Mode6Handler::leave_takeoff () } void -MK_VIII::Mode6Handler::set_volume (double volume) +MK_VIII::Mode6Handler::set_volume (float volume) { mk_voice(minimums_minimums)->set_volume(volume); mk_voice(five_hundred_above)->set_volume(volume); diff --git a/src/Instrumentation/mk_viii.hxx b/src/Instrumentation/mk_viii.hxx index 423562cfe..27cf023fa 100755 --- a/src/Instrumentation/mk_viii.hxx +++ b/src/Instrumentation/mk_viii.hxx @@ -36,6 +36,8 @@ using std::vector; using std::deque; using std::map; +class SGSampleGroup; + #include <Airports/runways.hxx> #include <Airports/simple.hxx> #include <Main/globals.hxx> @@ -733,10 +735,10 @@ public: public: bool silence; - virtual inline void play (double volume) {} + virtual inline void play (float volume) {} virtual inline void stop () {} virtual bool is_playing () = 0; - virtual inline void set_volume (double volume) {} + virtual inline void set_volume (float volume) {} }; ///////////////////////////////////////////////////////////////////////// @@ -746,16 +748,16 @@ public: class SampleElement : public Element { SGSoundSample *_sample; - double _volume; + float _volume; public: - inline SampleElement (SGSoundSample *sample, double volume = 1.0) + inline SampleElement (SGSoundSample *sample, float volume = 1.0) : _sample(sample), _volume(volume) { silence = false; } - virtual inline void play (double volume) { if (_sample) { set_volume(volume); _sample->play_once(); } } + virtual inline void play (float volume) { if (_sample && (volume > 0.05)) { set_volume(volume); _sample->play_once(); } } virtual inline void stop () { if (_sample) _sample->stop(); } virtual inline bool is_playing () { return _sample ? _sample->is_playing() : false; } - virtual inline void set_volume (double volume) { if (_sample) _sample->set_volume(volume * _volume); } + virtual inline void set_volume (float volume) { if (_sample) _sample->set_volume(volume * _volume); } }; ///////////////////////////////////////////////////////////////////////// @@ -771,7 +773,7 @@ public: inline SilenceElement (double duration) : _duration(duration) { silence = true; } - virtual inline void play (double volume) { start_time = globals->get_sim_time_sec(); } + virtual inline void play (float volume) { start_time = globals->get_sim_time_sec(); } virtual inline bool is_playing () { return globals->get_sim_time_sec() - start_time < _duration; } }; @@ -790,19 +792,19 @@ public: void play (); void stop (bool now); - void set_volume (double _volume); + void set_volume (float _volume); void volume_changed (); void update (); private: VoicePlayer *player; - double volume; + float volume; vector<Element *> elements; vector<Element *>::iterator iter; - inline double get_volume () const { return player->volume * player->speaker.volume * volume; } + inline float get_volume () const { return player->volume * player->speaker.volume * volume; } }; /////////////////////////////////////////////////////////////////////////// @@ -811,10 +813,10 @@ public: struct { - double volume; + float volume; } conf; - double volume; + float volume; Voice *voice; Voice *next_voice; @@ -871,7 +873,7 @@ public: }; void stop (unsigned int flags = 0); - void set_volume (double _volume); + void set_volume (float _volume); void update (); inline void bind (SGPropertyNode *node) { speaker.bind(node); } @@ -887,8 +889,8 @@ public: VoicePlayer *player; double pitch; - float position[3]; - float orientation[3]; + SGVec3d position; + SGVec3f orientation; float inner_cone; float outer_cone; float outer_gain; @@ -913,7 +915,7 @@ public: template <class T> inline T get_property (T *ptr) const { return *ptr; } - double volume; + float volume; inline Speaker (VoicePlayer *_player) : player(_player), @@ -940,6 +942,7 @@ public: MK_VIII *mk; + SGSampleGroup *_sgr; Speaker speaker; map<string, SGSoundSample *> samples; @@ -1465,7 +1468,7 @@ private: void power_off (); void enter_takeoff (); void leave_takeoff (); - void set_volume (double volume); + void set_volume (float volume); bool altitude_callouts_enabled (); void update (); diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx index ee217d6c9..f3b95c5e3 100644 --- a/src/Instrumentation/navradio.cxx +++ b/src/Instrumentation/navradio.cxx @@ -154,7 +154,8 @@ FGNavRadio::FGNavRadio(SGPropertyNode *node) : _name(node->getStringValue("name", "nav")), _num(node->getIntValue("number", 0)), _time_before_search_sec(-1.0), - _falseCoursesEnabled(true) + _falseCoursesEnabled(true), + _sgr(NULL) { SGPath path( globals->get_fg_root() ); SGPath term = path; @@ -182,6 +183,9 @@ FGNavRadio::~FGNavRadio() void FGNavRadio::init () { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("avionics", true); + morse.init(); string branch; @@ -768,17 +772,17 @@ void FGNavRadio::updateAudio() // play station ident via audio system if on + ident, // otherwise turn it off - if (!power_btn_node->getBoolValue() + if (!power_btn_node->getBoolValue() || !(bus_power_node->getDoubleValue() > 1.0) || !ident_btn_node->getBoolValue() || !audio_btn_node->getBoolValue() ) { - globals->get_soundmgr()->stop( nav_fx_name ); - globals->get_soundmgr()->stop( dme_fx_name ); + _sgr->stop( nav_fx_name ); + _sgr->stop( dme_fx_name ); return; } - SGSoundSample *sound = globals->get_soundmgr()->find( nav_fx_name ); - double vol = vol_btn_node->getDoubleValue(); + SGSoundSample *sound = _sgr->find( nav_fx_name ); + double vol = vol_btn_node->getFloatValue(); SG_CLAMP_RANGE(vol, 0.0, 1.0); if ( sound != NULL ) { @@ -787,7 +791,7 @@ void FGNavRadio::updateAudio() SG_LOG( SG_COCKPIT, SG_ALERT, "Can't find nav-vor-ident sound" ); } - sound = globals->get_soundmgr()->find( dme_fx_name ); + sound = _sgr->find( dme_fx_name ); if ( sound != NULL ) { sound->set_volume( vol ); } else { @@ -810,16 +814,16 @@ void FGNavRadio::updateAudio() play_count = ++play_count % NUM_IDENT_SLOTS; // Previous ident is out of time; if still playing, cut it off: - globals->get_soundmgr()->stop( nav_fx_name ); - globals->get_soundmgr()->stop( dme_fx_name ); + _sgr->stop( nav_fx_name ); + _sgr->stop( dme_fx_name ); if (play_count == 0) { // the DME slot if (_dmeInRange && dme_serviceable_node->getBoolValue()) { // play DME ident - globals->get_soundmgr()->play_once( dme_fx_name ); + if (vol > 0.05) _sgr->play_once( dme_fx_name ); } } else { // NAV slot if (inrange_node->getBoolValue() && nav_serviceable_node->getBoolValue()) { - globals->get_soundmgr()->play_once(nav_fx_name); + if (vol > 0.05) _sgr->play_once(nav_fx_name); } } } @@ -902,8 +906,9 @@ void FGNavRadio::search() _gs = NULL; _dme = NULL; nav_id_node->setStringValue(""); - globals->get_soundmgr()->remove( nav_fx_name ); - globals->get_soundmgr()->remove( dme_fx_name ); + + _sgr->remove( nav_fx_name ); + _sgr->remove( dme_fx_name ); } is_valid_node->setBoolValue(nav != NULL); @@ -945,25 +950,25 @@ double FGNavRadio::localizerWidth(FGNavRecord* aLOC) void FGNavRadio::audioNavidChanged() { - if ( globals->get_soundmgr()->exists(nav_fx_name)) { - globals->get_soundmgr()->remove(nav_fx_name); + if (_sgr->exists(nav_fx_name)) { + _sgr->remove(nav_fx_name); } try { string trans_ident(_navaid->get_trans_ident()); SGSoundSample* sound = morse.make_ident(trans_ident, LO_FREQUENCY); sound->set_volume( 0.3 ); - if (!globals->get_soundmgr()->add( sound, nav_fx_name )) { + if (!_sgr->add( sound, nav_fx_name )) { SG_LOG(SG_COCKPIT, SG_WARN, "Failed to add v1-vor-ident sound"); } - if ( globals->get_soundmgr()->exists( dme_fx_name ) ) { - globals->get_soundmgr()->remove( dme_fx_name ); + if ( _sgr->exists( dme_fx_name ) ) { + _sgr->remove( dme_fx_name ); } sound = morse.make_ident( trans_ident, HI_FREQUENCY ); sound->set_volume( 0.3 ); - globals->get_soundmgr()->add( sound, dme_fx_name ); + _sgr->add( sound, dme_fx_name ); int offset = (int)(sg_random() * 30.0); play_count = offset / 4; diff --git a/src/Instrumentation/navradio.hxx b/src/Instrumentation/navradio.hxx index 3ee3e4155..978e77d6f 100644 --- a/src/Instrumentation/navradio.hxx +++ b/src/Instrumentation/navradio.hxx @@ -35,6 +35,7 @@ // forward decls class SGInterpTable; +class SGSampleGroup; class FGNavRecord; typedef SGSharedPtr<FGNavRecord> FGNavRecordPtr; @@ -158,6 +159,8 @@ class FGNavRadio : public SGSubsystem // realism setting, are false courses and GS lobes enabled? bool _falseCoursesEnabled; + + SGSampleGroup *_sgr; bool updateWithPower(double aDt); diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 3f36555a0..ab6a15844 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -20,6 +20,7 @@ #include <simgear/structure/commands.hxx> #include <simgear/props/props.hxx> #include <simgear/structure/event_mgr.hxx> +#include <simgear/sound/soundmgr_openal.hxx> #include <Cockpit/panel.hxx> #include <Cockpit/panel_io.hxx> @@ -1251,13 +1252,17 @@ do_set_cursor (const SGPropertyNode * arg) static bool do_play_audio_sample (const SGPropertyNode * arg) { - FGFX *fx = (FGFX *)globals->get_subsystem("fx"); string path = arg->getStringValue("path"); string file = arg->getStringValue("file"); double volume = arg->getDoubleValue("volume"); // cout << "playing " << path << " / " << file << endl; try { - fx->play_message( path, file, volume ); + static FGFX *fx = 0; + if ( !fx ) { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + fx = (FGFX *)smgr->find("fx"); + } + if (fx) fx->play_message( path, file, volume ); return true; } catch (const sg_io_exception&) { diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index ab5742ac4..10bded7bb 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -136,6 +136,7 @@ using std::string; class Sound; +class SGSoundMgr; extern const char *default_root; float init_volume; @@ -1520,7 +1521,6 @@ bool fgInitSubsystems() { // Initialize the ridgelift subsystem globals->add_subsystem("ridgelift", new FGRidgeLift); - //////////////////////////////////////////////////////////////////// // Initialize the aircraft systems and instrumentation (before the // autopilot.) @@ -1582,22 +1582,9 @@ bool fgInitSubsystems() { fgGetBool("/sim/rendering/bump-mapping", false); #ifdef ENABLE_AUDIO_SUPPORT - //////////////////////////////////////////////////////////////////// - // Initialize the sound subsystem. - //////////////////////////////////////////////////////////////////// - - init_volume = fgGetFloat("/sim/sound/volume"); - fgSetFloat("/sim/sound/volume", 0.0f); - globals->set_soundmgr(new SGSoundMgr); - globals->get_soundmgr()->init(); - globals->get_soundmgr()->bind(); - - //////////////////////////////////////////////////////////////////// // Initialize the sound-effects subsystem. //////////////////////////////////////////////////////////////////// - - globals->add_subsystem("fx", new FGFX); globals->add_subsystem("voice", new FGVoiceMgr); #endif @@ -1680,6 +1667,19 @@ bool fgInitSubsystems() { //////////////////////////////////////////////////////////////////// globals->add_subsystem("replay", new FGReplay); + + //////////////////////////////////////////////////////////////////// + // Add Sound Manager. + // Put the sound manager last so it can use the CPU while the GPU + // is processing the scenery (doubled the frame-rate for me) -EMH- + //////////////////////////////////////////////////////////////////// +#ifdef ENABLE_AUDIO_SUPPORT + init_volume = fgGetFloat("/sim/sound/volume"); + fgSetFloat("/sim/sound/volume", 0.0f); + + globals->add_subsystem("soundmgr", new SGSoundMgr); +#endif + //////////////////////////////////////////////////////////////////// // Bind and initialize subsystems. //////////////////////////////////////////////////////////////////// diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index 1e8885c35..e3340b8a4 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -221,15 +221,17 @@ setFreeze (bool f) { frozen = f; +#if 0 // Stop sound on a pause - SGSoundMgr *s = globals->get_soundmgr(); - if ( s != NULL ) { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + if ( smgr != NULL ) { if ( f ) { - s->pause(); + smgr->suspend(); } else if (!fgGetBool("/sim/sound/pause")) { - s->resume(); + smgr->resume(); } } +#endif } diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 262423c2a..84cf9c932 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -24,7 +24,6 @@ # include <config.h> #endif -#include <simgear/sound/soundmgr_openal.hxx> #include <simgear/structure/commands.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/timing/sg_time.hxx> @@ -83,7 +82,6 @@ FGGlobals::FGGlobals() : matlib( NULL ), route_mgr( NULL ), current_panel( NULL ), - soundmgr( NULL ), ATC_mgr( NULL ), AI_mgr( NULL ), controls( NULL ), @@ -135,7 +133,6 @@ FGGlobals::~FGGlobals() delete matlib; delete route_mgr; delete current_panel; - delete soundmgr; delete ATC_mgr; delete AI_mgr; diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index a1c58797e..e778590dd 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -49,7 +49,6 @@ class SGMagVar; class SGMaterialLib; class SGPropertyNode; class SGTime; -class SGSoundMgr; class SGEventMgr; class SGSubsystemMgr; class SGSubsystem; @@ -132,9 +131,6 @@ private: // 2D panel FGPanel *current_panel; - // sound manager - SGSoundMgr *soundmgr; - // ATC manager FGATCMgr *ATC_mgr; @@ -244,9 +240,6 @@ public: inline FGPanel *get_current_panel() const { return current_panel; } inline void set_current_panel( FGPanel *cp ) { current_panel = cp; } - inline SGSoundMgr *get_soundmgr() const { return soundmgr; } - inline void set_soundmgr( SGSoundMgr *sm ) { soundmgr = sm; } - inline FGControls *get_controls() const { return controls; } inline void set_controls( FGControls *c ) { controls = c; } @@ -305,7 +298,7 @@ public: inline void set_tile_mgr ( FGTileMgr *t ) { tile_mgr = t; } inline FGFontCache *get_fontcache() const { return fontcache; } - + inline FGNavList *get_navlist() const { return navlist; } inline void set_navlist( FGNavList *n ) { navlist = n; } inline FGNavList *get_loclist() const { return loclist; } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index d16cbf4d6..023b4f87f 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -61,6 +61,7 @@ #include <Model/acmodel.hxx> #include <Scenery/scenery.hxx> #include <Scenery/tilemgr.hxx> +#include <Sound/fg_fx.hxx> #include <Sound/beacon.hxx> #include <Sound/morse.hxx> #include <Sound/fg_fx.hxx> @@ -477,19 +478,14 @@ static void fgMainLoop( void ) { // update the view angle as late as possible, but before sound calculations globals->get_viewmgr()->update(real_delta_time_sec); - // Run audio scheduler -#ifdef ENABLE_AUDIO_SUPPORT - FGFX* fx = (FGFX*) globals->get_subsystem("fx"); - fx->update_fx_late(delta_time_sec); -#endif - // END Tile Manager udpates if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded() && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); fgSetFloat("/sim/sound/volume", init_volume); - globals->get_soundmgr()->set_volume(init_volume); + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + smgr->set_volume(init_volume); } fgRequestRedraw(); @@ -723,13 +719,13 @@ static void fgIdleFunction ( void ) { SG_LOG( SG_GENERAL, SG_INFO, "Starting intro music: " << mp3file.str() ); -#if defined( __CYGWIN__ ) +# if defined( __CYGWIN__ ) string command = "start /m `cygpath -w " + mp3file.str() + "`"; -#elif defined( WIN32 ) +# elif defined( WIN32 ) string command = "start /m " + mp3file.str(); -#else +# else string command = "mpg123 " + mp3file.str() + "> /dev/null 2>&1"; -#endif +# endif system ( command.c_str() ); } diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 596f343ae..8f865265c 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -30,6 +30,7 @@ #include <string.h> // strcmp #include <simgear/compiler.h> +#include <simgear/sound/soundmgr_openal.hxx> #include <Model/acmodel.hxx> #include <Main/viewer.hxx> #include <Main/fg_props.hxx> @@ -293,6 +294,17 @@ FGViewMgr::update (double dt) do_axes(); view->update(dt); abs_viewer_position = loop_view->getViewPosition(); + + // update audio listener values + static SGSoundMgr *smgr = 0; + if (!smgr) smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + if (smgr) { + // set the viewer posotion in Cartesian coordinates in meters + smgr->set_position(abs_viewer_position); + smgr->set_orientation(loop_view->getViewOrientation()); +//TODO: should be in meters per second +// smr->set_veloicty(SGVec3f(0,0,0)); + } } void diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index a1721228a..866c09188 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -22,18 +22,30 @@ #include <Main/viewmgr.hxx> #include <Main/viewer.hxx> #include <Scenery/scenery.hxx> +#include <Sound/fg_fx.hxx> #include "model_panel.hxx" #include "acmodel.hxx" + //////////////////////////////////////////////////////////////////////// // Implementation of FGAircraftModel //////////////////////////////////////////////////////////////////////// FGAircraftModel::FGAircraftModel () - : _aircraft(0) + : _aircraft(0), + _fx(0), + _lon(0), + _lat(0), + _alt(0), + _pitch(0), + _roll(0), + _heading(0), + _speed_north(0), + _speed_east(0), + _speed_up(0) { } @@ -70,7 +82,15 @@ FGAircraftModel::init () void FGAircraftModel::bind () { - // No-op + _lon = fgGetNode("position/longitude-deg", true); + _lat = fgGetNode("position/latitude-deg", true); + _alt = fgGetNode("position/altitude-ft", true); + _pitch = fgGetNode("orientation/pitch-deg", true); + _roll = fgGetNode("orientation/roll-deg", true); + _heading = fgGetNode("orientation/heading-deg", true); + _speed_north = fgGetNode("/velocities/speed-north-fps", true); + _speed_east = fgGetNode("/velocities/speed-east-fps", true); + _speed_up = fgGetNode("/velocities/vertical-speed-fps", true); } void @@ -91,13 +111,41 @@ FGAircraftModel::update (double dt) _aircraft->setVisible(true); } - _aircraft->setPosition(fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"), - fgGetDouble("/position/altitude-ft")); - _aircraft->setOrientation(fgGetDouble("/orientation/roll-deg"), - fgGetDouble("/orientation/pitch-deg"), - fgGetDouble("/orientation/heading-deg")); + _aircraft->setPosition(_lon->getDoubleValue(), + _lat->getDoubleValue(), + _alt->getDoubleValue()); + _aircraft->setOrientation(_roll->getDoubleValue(), + _pitch->getDoubleValue(), + _heading->getDoubleValue()); _aircraft->update(); + + if ( !_fx) { + SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + if (smgr) { + _fx = new FGFX(smgr, "fx"); + _fx->init(); + } + } + + if (_fx) { + // Get the Cartesian coordinates in meters + SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); + _fx->set_position( pos ); + + SGQuatd orient_m = SGQuatd::fromLonLat(_aircraft->getPosition()); + orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), + _pitch->getDoubleValue(), + _roll->getDoubleValue()); + SGVec3d orient = orient_m.rotateBack(SGVec3d::e1()); + _fx->set_orientation( toVec3f(orient) ); + + SGVec3f vel = SGVec3f( _speed_north->getFloatValue(), + _speed_east->getFloatValue(), + _speed_up->getFloatValue()); +// TODO: rotate to properly align with the model orientation + + _fx->set_velocity( vel*SG_FEET_TO_METER ); + } } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index 16fc45527..da728fcf6 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -25,7 +25,7 @@ using std::vector; // Don't pull in the headers, since we don't need them here. class SGModelPlacement; - +class FGFX; class FGAircraftModel : public SGSubsystem { @@ -43,6 +43,18 @@ public: private: SGModelPlacement * _aircraft; + FGFX * _fx; + + SGPropertyNode * _lon; + SGPropertyNode * _lat; + SGPropertyNode * _alt; + SGPropertyNode * _pitch; + SGPropertyNode * _roll; + SGPropertyNode * _heading; + SGPropertyNode * _speed_north; + SGPropertyNode * _speed_east; + SGPropertyNode * _speed_up; + }; #endif // __ACMODEL_HXX diff --git a/src/Sound/beacon.cxx b/src/Sound/beacon.cxx index 41a990271..9b5f353af 100644 --- a/src/Sound/beacon.cxx +++ b/src/Sound/beacon.cxx @@ -24,8 +24,6 @@ #include "beacon.hxx" #include <simgear/structure/exception.hxx> -#include <Main/fg_props.hxx> -#include <Main/globals.hxx> // constructor FGBeacon::FGBeacon() @@ -43,13 +41,9 @@ bool FGBeacon::init() { int len; unsigned char *ptr; - if (globals->get_soundmgr()->is_working() == false) { - return false; - } - - unsigned char inner_buf[ INNER_SIZE ] ; - unsigned char middle_buf[ MIDDLE_SIZE ] ; - unsigned char outer_buf[ OUTER_SIZE ] ; + unsigned char *inner_buf = new unsigned char[ INNER_SIZE ] ; + unsigned char *middle_buf = new unsigned char[ MIDDLE_SIZE ] ; + unsigned char *outer_buf = new unsigned char[ OUTER_SIZE ] ; // Make inner marker beacon sound len= (int)(INNER_DIT_LEN / 2.0 ); @@ -99,7 +93,7 @@ bool FGBeacon::init() { ptr += OUTER_DAH_LEN; memcpy( ptr, outer_dah, OUTER_DAH_LEN ); - outer = new SGSoundSample( outer_buf, OUTER_SIZE, BYTES_PER_SECOND); + outer = new SGSoundSample( outer_buf, OUTER_SIZE, BYTES_PER_SECOND ); outer->set_reference_dist( 10.0 ); outer->set_max_dist( 20.0 ); } catch ( sg_io_exception &e ) { diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 50d39479d..da6fcece3 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -35,8 +35,8 @@ #include <simgear/structure/exception.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/props/props.hxx> -#include <simgear/sound/xmlsound.hxx> #include <simgear/sound/soundmgr_openal.hxx> +#include <simgear/sound/xmlsound.hxx> #include <Main/fg_props.hxx> @@ -44,7 +44,7 @@ #include <Model/acmodel.hxx> #include <Main/viewer.hxx> -FGFX::FGFX () : +FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : last_visitor_pos(SGVec3d::zeros()), last_model_pos(SGVec3d::zeros()), last_pause( true ), @@ -52,8 +52,12 @@ FGFX::FGFX () : _pause( fgGetNode("/sim/sound/pause") ), _volume( fgGetNode("/sim/sound/volume") ) { + SGSampleGroup::_smgr = smgr; + SGSampleGroup::_smgr->add(this, refname); + SGSampleGroup::_active = _smgr->is_working(); } + FGFX::~FGFX () { unsigned int i; @@ -68,6 +72,7 @@ FGFX::~FGFX () } } + void FGFX::init() { @@ -99,8 +104,8 @@ FGFX::init() SGXmlSound *sound = new SGXmlSound(); try { - sound->init(globals->get_props(), node->getChild(i), - globals->get_soundmgr(), globals->get_fg_root()); + sound->init(globals->get_props(), node->getChild(i), this, + globals->get_fg_root()); _sound.push_back(sound); } catch ( sg_exception &e ) { @@ -111,89 +116,65 @@ FGFX::init() } } + void FGFX::reinit() { - _sound.clear(); - init(); + _sound.clear(); + init(); }; -void -FGFX::bind () -{ -} - -void -FGFX::unbind () -{ -} void FGFX::update (double dt) { - SGSoundMgr *smgr = globals->get_soundmgr(); - - if (smgr->is_working() == false) { - return; - } - // command sound manger - bool pause = _pause->getBoolValue(); - if ( pause != last_pause ) { - if ( pause ) { - smgr->pause(); + bool new_pause = _pause->getBoolValue(); + if ( new_pause != last_pause ) { + if ( new_pause ) { + suspend(); } else { - smgr->resume(); + resume(); } - last_pause = pause; + last_pause = new_pause; } // process mesage queue const string msgid = "Sequential Audio Message"; - bool is_playing = false; - if ( smgr->exists( msgid ) ) { - if ( smgr->is_playing( msgid ) ) { + bool now_playing = false; + if ( exists( msgid ) ) { + if ( is_playing( msgid ) ) { // still playing, do nothing - is_playing = true; + now_playing = true; } else { // current message finished, stop and remove - smgr->stop( msgid ); // removes source - smgr->remove( msgid ); // removes buffer + stop( msgid ); // removes source + remove( msgid ); // removes buffer } } - if ( !is_playing ) { + if ( !now_playing ) { // message queue idle, add next sound if we have one if ( _samplequeue.size() > 0 ) { - smgr->add( _samplequeue.front(), msgid ); + add( _samplequeue.front(), msgid ); _samplequeue.pop(); - smgr->play_once( msgid ); + play_once( msgid ); } } double volume = _volume->getDoubleValue(); if ( volume != last_volume ) { - smgr->set_volume( volume ); + set_volume( volume ); last_volume = volume; } - if ( !pause ) { + if ( !new_pause ) { // update sound effects if not paused for ( unsigned int i = 0; i < _sound.size(); i++ ) { _sound[i]->update(dt); } } -} -void -FGFX::update_fx_late(double dt) -{ - SGSoundMgr *smgr = globals->get_soundmgr(); - if (!smgr->is_working()) { - return; - } - - smgr->update(dt); - update_pos_and_orientation(smgr, dt); + SGSampleGroup::update(dt); } /** @@ -203,100 +184,14 @@ FGFX::update_fx_late(double dt) void FGFX::play_message( SGSoundSample *_sample ) { - _samplequeue.push( _sample ); + _samplequeue.push( _sample ); } void FGFX::play_message( const std::string& path, const std::string& fname, double volume ) { - if (globals->get_soundmgr()->is_working() == true) { - SGSoundSample *sample; - sample = new SGSoundSample( path.c_str(), fname.c_str() ); - sample->set_volume( volume ); - play_message( sample ); - } -} - -void -FGFX::update_pos_and_orientation(SGSoundMgr *smgr, double dt) -{ - SGModelPlacement *model = globals->get_aircraft_model()->get3DModel(); - FGViewer *observer = globals->get_current_view(); - - // Right now we make a simplifying assumption that the primary - // aircraft is the source of all sounds and that all sounds are - // positioned in the aircraft base - // EMH: Note: this is fine, to hear multiple aircraft simulataniously - // we just have to trigger one instance of the FGFX class for every - // aircraft - - // get the orientation - const SGQuatd view_or = observer->getViewOrientation(); - SGQuatd surf_or = SGQuatd::fromLonLat(observer->getPosition()); - - SGQuatd model_or = SGQuatd::fromYawPitchRollDeg( - model->getHeadingDeg(), - model->getPitchDeg(), - model->getRollDeg()); - - // get the up and at vector in the aircraft base - // (ok, the up vector is a down vector, but the coordinates - // are finally calculated in a left hand system and openal - // lives in a right hand system. Therefore we need to pass - // the down vector to get correct stereo sound.) - SGVec3d sgv_up - = model_or.rotateBack(surf_or.rotateBack(view_or.rotate(SGVec3d(0,1,0)))); - SGVec3d sgv_at - = model_or.rotateBack(surf_or.rotateBack(view_or.rotate(SGVec3d(0,0,1)))); - - // get the location data for the primary FDM (now hardcoded to ac model)... - // EMH: to add multiple sound sources this should be replaced - SGVec3d absolute_view_pos = SGVec3d::fromGeod(model->getPosition()); - - // calculate speed of visitor and model - SGVec3d moved = last_visitor_pos - observer->get_view_pos(); - last_visitor_pos = observer->get_view_pos(); - SGVec3f listener_vel(model_or.rotateBack(surf_or.rotateBack(moved))); - - moved = last_model_pos - absolute_view_pos; - last_model_pos = absolute_view_pos; - SGVec3f model_vel(model_or.rotateBack(surf_or.rotateBack(moved))); - - if (dt > 0) { - model_vel /= dt; - listener_vel /= dt; - } - - // checking, if the listener pos has moved suddenly - if (length(listener_vel) > 1000) { - // check if the relative speed model vs listener has moved suddenly, too - SGVec3f delta_vel = listener_vel - model_vel; - if (length(delta_vel) > 1000) - // a sane value - smgr->set_listener_vel(model_vel.data()); - else - smgr->set_listener_vel(listener_vel.data()); - } else { - smgr->set_listener_vel( listener_vel.data()); - } - - // set positional offset for sources - SGVec3d dsource_pos_offset = observer->get_view_pos() - absolute_view_pos; - dsource_pos_offset = model_or.rotateBack(surf_or.rotateBack( - dsource_pos_offset - )); - - smgr->set_source_pos_all( SGVec3f(dsource_pos_offset).data() ); - smgr->set_source_vel_all(model_vel.data() ); - - float orient[6]; - for (int i = 0; i < 3; i++) { - orient[i] = sgv_at[i]; - orient[i + 3] = sgv_up[i]; - } - smgr->set_listener_orientation( orient ); - - // The listener is always positioned at the origin. - smgr->set_listener_pos( SGVec3f::zeros().data() ); + SGSoundSample *sample = new SGSoundSample( path.c_str(), fname.c_str() ); + sample->set_volume( volume ); + play_message( sample ); } // end of fg_fx.cxx diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index 1f7138bc1..76d38915f 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -30,16 +30,15 @@ #include <vector> #include <simgear/structure/subsystem_mgr.hxx> +#include <simgear/sound/sample_group.hxx> #include <simgear/math/SGMath.hxx> class SGXmlSound; -class SGSoundSample; -class SGSoundMgr; /** * Generator for FlightGear sound effects. * - * This module uses FGSoundMgr to generate sound effects based + * This module uses a FGSampleGroup class to generate sound effects based * on current flight conditions. The sound manager must be initialized * before this object is. * @@ -52,18 +51,16 @@ class SGSoundMgr; * This second mechanims is useful for things like tutorial messages or * background atc chatter. */ -class FGFX : public SGSubsystem +class FGFX : public SGSampleGroup { public: - FGFX (); + FGFX ( SGSoundMgr *smgr, const string &refname ); virtual ~FGFX (); virtual void init (); virtual void reinit (); - virtual void bind (); - virtual void unbind (); virtual void update (double dt); /** @@ -73,15 +70,10 @@ public: void play_message( SGSoundSample *_sample ); void play_message( const std::string& path, const std::string& fname, double volume ); - /** - * Explicit late update hook, to avoid problems which occur if done during - * normal SGSubsytem updating. - */ - void update_fx_late(double dt); - private: - void update_pos_and_orientation(SGSoundMgr *smgr, double dt); + void update_pos_and_orientation(double dt); + SGVec3d last_visitor_pos; SGVec3d last_model_pos; diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx index 754c98eb3..a56273288 100644 --- a/src/Sound/morse.cxx +++ b/src/Sound/morse.cxx @@ -23,9 +23,6 @@ #include <simgear/constants.h> -#include <Main/fg_props.hxx> -#include <Main/globals.hxx> - #include "morse.hxx" @@ -171,10 +168,6 @@ bool FGMorse::cust_init(const int freq ) { // make a SGSoundSample morse code transmission for the specified string SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) { - if (globals->get_soundmgr()->is_working() == false) { - return 0; - } - char *idptr = (char *)id.c_str(); int length = 0; @@ -271,9 +264,6 @@ SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) { SGSoundSample *sample = new SGSoundSample( buffer, length, BYTES_PER_SECOND ); - // clean up the buffer - delete [] buffer; - sample->set_reference_dist( 10.0 ); sample->set_max_dist( 20.0 ); From 446b200edc9590ec1e0231e64084905f2bc8a5b9 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 5 Oct 2009 09:12:50 +0000 Subject: [PATCH 02/62] Add the Sound Manager before any other subsystem that uses it. This makes sure the SoundMgr is available at construction time which makes the code much cleaner. Call the update_last() after any other class --- src/ATCDCL/AIPlane.cxx | 14 ++++++++------ src/ATCDCL/AIPlane.hxx | 2 +- src/ATCDCL/ATC.cxx | 8 +++----- src/Main/fg_init.cxx | 18 +----------------- src/Main/fg_props.cxx | 2 -- src/Main/main.cxx | 22 +++++++++++++++++++++- src/Main/viewmgr.cxx | 14 +++++--------- src/Main/viewmgr.hxx | 3 +++ src/Model/acmodel.cxx | 41 ++++++++++++++++++----------------------- 9 files changed, 60 insertions(+), 64 deletions(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 1db5820ec..f672676eb 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -29,6 +29,8 @@ using std::string; #include "AIPlane.hxx" +SGSampleGroup *FGAIPlane::_sgr = 0; + FGAIPlane::FGAIPlane() { leg = LEG_UNKNOWN; tuned_station = NULL; @@ -47,18 +49,18 @@ FGAIPlane::FGAIPlane() { _trackSet = false; _tgtRoll = 0.0; _rollSuspended = false; - _sgr = 0; + + if ( !_sgr ) { + SGSoundMgr *smgr; + smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("atc", true); + } } FGAIPlane::~FGAIPlane() { } void FGAIPlane::Update(double dt) { - if (!_sgr) { - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); - if (smgr) _sgr = smgr->find("atc", true); - } - if(_pending) { if(tuned_station) { if(tuned_station->GetFreqClear()) { diff --git a/src/ATCDCL/AIPlane.hxx b/src/ATCDCL/AIPlane.hxx index aba6e7b7e..e099cdfac 100644 --- a/src/ATCDCL/AIPlane.hxx +++ b/src/ATCDCL/AIPlane.hxx @@ -160,7 +160,7 @@ private: double _tgtRoll; bool _rollSuspended; // Set true when a derived class has suspended AIPlane's roll control - SGSampleGroup *_sgr; + static SGSampleGroup *_sgr; }; #endif // _FG_AI_PLANE_HXX diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index ed62bad03..92568edc5 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -56,6 +56,9 @@ FGATC::FGATC() : _counter(0.0), _max_count(5.0) { + SGSoundMgr *smgr; + smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _sgr = smgr->find("atc", true); } FGATC::~FGATC() { @@ -238,11 +241,6 @@ void FGATC::Render(string& msg, const float volume, new SGSoundSample((unsigned char*) buf.c_str(), buf.length(), 8000); // TODO - at the moment the volume can't be changed // after the transmission has started. - if (!_sgr) { - SGSoundMgr *smgr; - smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); - _sgr = smgr->find("atc", true); - } simple->set_volume(volume); _sgr->add(simple, refname); _sgr->play(refname, repeating); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 10bded7bb..92d32a1ca 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -57,6 +57,7 @@ #include <simgear/misc/interpolator.hxx> #include <simgear/scene/material/matlib.hxx> #include <simgear/scene/model/particles.hxx> +#include <simgear/sound/soundmgr_openal.hxx> #include <simgear/timing/sg_time.hxx> #include <simgear/timing/lowleveltime.h> @@ -103,9 +104,6 @@ #include <Scenery/scenery.hxx> #include <Scenery/tilemgr.hxx> #include <Scripting/NasalSys.hxx> -#include <Sound/fg_fx.hxx> -#include <Sound/beacon.hxx> -#include <Sound/morse.hxx> #include <Sound/voice.hxx> #include <Systems/system_mgr.hxx> #include <Time/light.hxx> @@ -135,8 +133,6 @@ using std::string; -class Sound; -class SGSoundMgr; extern const char *default_root; float init_volume; @@ -1668,18 +1664,6 @@ bool fgInitSubsystems() { globals->add_subsystem("replay", new FGReplay); - //////////////////////////////////////////////////////////////////// - // Add Sound Manager. - // Put the sound manager last so it can use the CPU while the GPU - // is processing the scenery (doubled the frame-rate for me) -EMH- - //////////////////////////////////////////////////////////////////// -#ifdef ENABLE_AUDIO_SUPPORT - init_volume = fgGetFloat("/sim/sound/volume"); - fgSetFloat("/sim/sound/volume", 0.0f); - - globals->add_subsystem("soundmgr", new SGSoundMgr); -#endif - //////////////////////////////////////////////////////////////////// // Bind and initialize subsystems. //////////////////////////////////////////////////////////////////// diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index e3340b8a4..6a54db665 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -221,7 +221,6 @@ setFreeze (bool f) { frozen = f; -#if 0 // Stop sound on a pause SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); if ( smgr != NULL ) { @@ -231,7 +230,6 @@ setFreeze (bool f) smgr->resume(); } } -#endif } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 023b4f87f..390aeb3b8 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -478,14 +478,24 @@ static void fgMainLoop( void ) { // update the view angle as late as possible, but before sound calculations globals->get_viewmgr()->update(real_delta_time_sec); + //////////////////////////////////////////////////////////////////// + // Update the sound manager last so it can use the CPU while the GPU + // is processing the scenery (doubled the frame-rate for me) -EMH- + //////////////////////////////////////////////////////////////////// +#ifdef ENABLE_AUDIO_SUPPORT + static SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + smgr->update_late(delta_time_sec); +#endif + // END Tile Manager udpates if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded() && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); fgSetFloat("/sim/sound/volume", init_volume); - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); +#ifdef ENABLE_AUDIO_SUPPORT smgr->set_volume(init_volume); +#endif } fgRequestRedraw(); @@ -623,6 +633,16 @@ static void fgIdleFunction ( void ) { } else if ( idle_state == 5 ) { idle_state++; +#ifdef ENABLE_AUDIO_SUPPORT + //////////////////////////////////////////////////////////////////// + // Add the Sound Manager before any other subsystem that uses it. + // This makes sure the SoundMgr is available at construction time. + //////////////////////////////////////////////////////////////////// + init_volume = fgGetFloat("/sim/sound/volume"); + fgSetFloat("/sim/sound/volume", 0.0f); + globals->add_subsystem("soundmgr", new SGSoundMgr); +#endif + //////////////////////////////////////////////////////////////////// // Initialize the 3D aircraft model subsystem (has a dependency on // the scenery subsystem.) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 8f865265c..20db9476b 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -43,6 +43,7 @@ FGViewMgr::FGViewMgr( void ) : config_list(fgGetNode("/sim", true)->getChildren("view")), current(0) { + smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); } // Destructor @@ -296,15 +297,10 @@ FGViewMgr::update (double dt) abs_viewer_position = loop_view->getViewPosition(); // update audio listener values - static SGSoundMgr *smgr = 0; - if (!smgr) smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); - if (smgr) { - // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position(abs_viewer_position); - smgr->set_orientation(loop_view->getViewOrientation()); -//TODO: should be in meters per second -// smr->set_veloicty(SGVec3f(0,0,0)); - } + // set the viewer posotion in Cartesian coordinates in meters + smgr->set_position(abs_viewer_position); + smgr->set_orientation(loop_view->getViewOrientation()); + smgr->set_velocity(SGVec3f(0,0,0)); // TODO: in meters per second } void diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 2955ac845..76ede702e 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -32,6 +32,7 @@ // forward decls class FGViewer; +class SGSoundMgr; typedef SGSharedPtr<FGViewer> FGViewerPtr; // Define a structure containing view information @@ -124,6 +125,8 @@ private: int current; + SGSoundMgr *smgr; + }; diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 866c09188..f54e4721e 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -47,6 +47,10 @@ FGAircraftModel::FGAircraftModel () _speed_east(0), _speed_up(0) { + SGSoundMgr *smgr; + smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + _fx = new FGFX(smgr, "fx"); + _fx->init(); } FGAircraftModel::~FGAircraftModel () @@ -119,33 +123,24 @@ FGAircraftModel::update (double dt) _heading->getDoubleValue()); _aircraft->update(); - if ( !_fx) { - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); - if (smgr) { - _fx = new FGFX(smgr, "fx"); - _fx->init(); - } - } + // update model's sample group values + // Get the Cartesian coordinates in meters + SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); + _fx->set_position( pos ); - if (_fx) { - // Get the Cartesian coordinates in meters - SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); - _fx->set_position( pos ); - - SGQuatd orient_m = SGQuatd::fromLonLat(_aircraft->getPosition()); - orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), - _pitch->getDoubleValue(), - _roll->getDoubleValue()); - SGVec3d orient = orient_m.rotateBack(SGVec3d::e1()); - _fx->set_orientation( toVec3f(orient) ); + SGQuatd orient_m = SGQuatd::fromLonLat(_aircraft->getPosition()); + orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), + _pitch->getDoubleValue(), + _roll->getDoubleValue()); + SGVec3d orient = orient_m.rotateBack(SGVec3d::e1()); + _fx->set_orientation( toVec3f(orient) ); - SGVec3f vel = SGVec3f( _speed_north->getFloatValue(), - _speed_east->getFloatValue(), - _speed_up->getFloatValue()); + SGVec3f vel = SGVec3f( _speed_north->getFloatValue(), + _speed_east->getFloatValue(), + _speed_up->getFloatValue()); // TODO: rotate to properly align with the model orientation - _fx->set_velocity( vel*SG_FEET_TO_METER ); - } + _fx->set_velocity( vel*SG_FEET_TO_METER ); } From b64259b2950d6bf0e6572e3362b6ee109104192e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 5 Oct 2009 13:47:03 +0000 Subject: [PATCH 03/62] allow disabling sound completely (note: openal gets initialized but shuts down a bit later leaving the soundmanager to handle only very specific commands). At this time by specifying '--prop:/sim/sound/enabled=false', not sure why '--disable-sound' doesn't work properly --- src/Main/fg_init.cxx | 1 - src/Main/main.cxx | 9 ++++----- src/Main/options.cxx | 5 +++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 92d32a1ca..a78759c42 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -134,7 +134,6 @@ using std::string; extern const char *default_root; -float init_volume; // Scan the command line options for the specified option and return diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 390aeb3b8..91e1542db 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -87,7 +87,6 @@ static double real_delta_time_sec = 0.0; double delta_time_sec = 0.0; -extern float init_volume; using namespace flightgear; @@ -492,9 +491,11 @@ static void fgMainLoop( void ) { if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded() && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); - fgSetFloat("/sim/sound/volume", init_volume); #ifdef ENABLE_AUDIO_SUPPORT - smgr->set_volume(init_volume); + if (fgGetBool("/sim/sound/enabled") == false) + smgr->stop(); + else + smgr->set_volume(fgGetFloat("/sim/sound/volume")); #endif } @@ -638,8 +639,6 @@ static void fgIdleFunction ( void ) { // Add the Sound Manager before any other subsystem that uses it. // This makes sure the SoundMgr is available at construction time. //////////////////////////////////////////////////////////////////// - init_volume = fgGetFloat("/sim/sound/volume"); - fgSetFloat("/sim/sound/volume", 0.0f); globals->add_subsystem("soundmgr", new SGSoundMgr); #endif diff --git a/src/Main/options.cxx b/src/Main/options.cxx index ad17068e6..73ebf0627 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -186,6 +186,7 @@ fgSetDefaults () fgSetBool("/sim/hud/enable3d", true); fgSetBool("/sim/hud/visibility", false); fgSetBool("/sim/panel/visibility", true); + fgSetBool("/sim/sound/enabled", true); fgSetBool("/sim/sound/pause", false); // Flight Model options @@ -1290,8 +1291,8 @@ struct OptionDesc { {"enable-hud", false, OPTION_BOOL, "/sim/hud/visibility", true, "", 0 }, {"disable-panel", false, OPTION_BOOL, "/sim/panel/visibility", false, "", 0 }, {"enable-panel", false, OPTION_BOOL, "/sim/panel/visibility", true, "", 0 }, - {"disable-sound", false, OPTION_BOOL, "/sim/sound/pause", true, "", 0 }, - {"enable-sound", false, OPTION_BOOL, "/sim/sound/pause", false, "", 0 }, + {"disable-sound", false, OPTION_BOOL, "/sim/sound/enabled", true, "", 0 }, + {"enable-sound", false, OPTION_BOOL, "/sim/sound/enabled", false, "", 0 }, {"airport", true, OPTION_STRING, "/sim/presets/airport-id", false, "", 0 }, {"runway", true, OPTION_FUNC, "", false, "", fgOptRunway }, {"vor", true, OPTION_FUNC, "", false, "", fgOptVOR }, From 5107a9d07fe6a0e976fb7ab0d6fee4c2552e7887 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 6 Oct 2009 12:09:50 +0000 Subject: [PATCH 04/62] (try to) properly align model and viewer --- src/Main/viewmgr.cxx | 7 ++++++- src/Model/acmodel.cxx | 26 +++++++++++++------------- src/Model/acmodel.hxx | 5 +++-- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 20db9476b..d429c219c 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -248,6 +248,7 @@ FGViewMgr::update (double dt) FGViewer *loop_view = (FGViewer *)get_view(current); SGPropertyNode *n = config_list[current]; double lon_deg, lat_deg, alt_ft, roll_deg, pitch_deg, heading_deg; + SGVec3f velocity = SGVec3f(0,0,0); // Set up view location and orientation @@ -264,6 +265,10 @@ FGViewMgr::update (double dt) } else { // force recalc in viewer loop_view->set_dirty(); + + // get the model velocity for the in-cockpit view + FGAircraftModel *aircraft = globals->get_aircraft_model(); + velocity = aircraft->getVelocity(); } // if lookat (type 1) then get target data... @@ -300,7 +305,7 @@ FGViewMgr::update (double dt) // set the viewer posotion in Cartesian coordinates in meters smgr->set_position(abs_viewer_position); smgr->set_orientation(loop_view->getViewOrientation()); - smgr->set_velocity(SGVec3f(0,0,0)); // TODO: in meters per second + smgr->set_velocity(velocity); } void diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index f54e4721e..0541a1159 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -36,6 +36,7 @@ FGAircraftModel::FGAircraftModel () : _aircraft(0), + _velocity(SGVec3f::zeros()), _fx(0), _lon(0), _lat(0), @@ -43,8 +44,7 @@ FGAircraftModel::FGAircraftModel () _pitch(0), _roll(0), _heading(0), - _speed_north(0), - _speed_east(0), + _speed(0), _speed_up(0) { SGSoundMgr *smgr; @@ -92,9 +92,8 @@ FGAircraftModel::bind () _pitch = fgGetNode("orientation/pitch-deg", true); _roll = fgGetNode("orientation/roll-deg", true); _heading = fgGetNode("orientation/heading-deg", true); - _speed_north = fgGetNode("/velocities/speed-north-fps", true); - _speed_east = fgGetNode("/velocities/speed-east-fps", true); - _speed_up = fgGetNode("/velocities/vertical-speed-fps", true); + _speed = fgGetNode("velocities/true-airspeed-kt", true); + _speed_up = fgGetNode("velocities/vertical-speed-fps", true); } void @@ -123,7 +122,7 @@ FGAircraftModel::update (double dt) _heading->getDoubleValue()); _aircraft->update(); - // update model's sample group values + // update model's audio sample values // Get the Cartesian coordinates in meters SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); _fx->set_position( pos ); @@ -132,15 +131,16 @@ FGAircraftModel::update (double dt) orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), _pitch->getDoubleValue(), _roll->getDoubleValue()); - SGVec3d orient = orient_m.rotateBack(SGVec3d::e1()); + SGVec3d orient = -orient_m.rotate(SGVec3d::e1()); _fx->set_orientation( toVec3f(orient) ); - SGVec3f vel = SGVec3f( _speed_north->getFloatValue(), - _speed_east->getFloatValue(), - _speed_up->getFloatValue()); -// TODO: rotate to properly align with the model orientation - - _fx->set_velocity( vel*SG_FEET_TO_METER ); + // For now assume the aircraft speed is always along the longitudinal + // axis, so sideslipping is not taken into account. This should be fine + // for audio. + _velocity = toVec3f(orient * _speed->getDoubleValue() * SG_KT_TO_FPS); + // _velocity[2] = _speed_up->getFloatValue(); + _velocity *= SG_FEET_TO_METER; + _fx->set_velocity( _velocity ); } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index da728fcf6..5a0b31a0e 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -39,10 +39,12 @@ public: virtual void unbind (); virtual void update (double dt); virtual SGModelPlacement * get3DModel() { return _aircraft; } + virtual SGVec3f getVelocity() { return _velocity; } private: SGModelPlacement * _aircraft; + SGVec3f _velocity; FGFX * _fx; SGPropertyNode * _lon; @@ -51,8 +53,7 @@ private: SGPropertyNode * _pitch; SGPropertyNode * _roll; SGPropertyNode * _heading; - SGPropertyNode * _speed_north; - SGPropertyNode * _speed_east; + SGPropertyNode * _speed; SGPropertyNode * _speed_up; }; From c56113d0dd0bba31bf1788a79694c966e5a1c477 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 7 Oct 2009 12:55:08 +0000 Subject: [PATCH 05/62] add the option to tie a SampleGroup to the listener position and orientation --- src/ATCDCL/AIPlane.cxx | 1 + src/Instrumentation/adf.cxx | 1 + src/Instrumentation/kr_87.cxx | 1 + src/Instrumentation/marker_beacon.cxx | 1 + src/Instrumentation/mk_viii.cxx | 1 + src/Instrumentation/navradio.cxx | 1 + 6 files changed, 6 insertions(+) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index f672676eb..eecc070d9 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -54,6 +54,7 @@ FGAIPlane::FGAIPlane() { SGSoundMgr *smgr; smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("atc", true); + _sgr->tie_to_listener(); } } diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx index d2ac69145..9f9ba2d83 100644 --- a/src/Instrumentation/adf.cxx +++ b/src/Instrumentation/adf.cxx @@ -104,6 +104,7 @@ ADF::init () SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("avionics", true); + _sgr->tie_to_listener(); morse.init(); diff --git a/src/Instrumentation/kr_87.cxx b/src/Instrumentation/kr_87.cxx index eab9bf69b..d0087c098 100644 --- a/src/Instrumentation/kr_87.cxx +++ b/src/Instrumentation/kr_87.cxx @@ -119,6 +119,7 @@ FGKR_87::~FGKR_87() { void FGKR_87::init () { SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("avionics", true); + _sgr->tie_to_listener(); morse.init(); } diff --git a/src/Instrumentation/marker_beacon.cxx b/src/Instrumentation/marker_beacon.cxx index ccb8499e1..3a0d33819 100644 --- a/src/Instrumentation/marker_beacon.cxx +++ b/src/Instrumentation/marker_beacon.cxx @@ -119,6 +119,7 @@ FGMarkerBeacon::init () SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("avionics", true); + _sgr->tie_to_listener(); morse.init(); beacon.init(); diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index 3cdc6e3ef..e484127f7 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2217,6 +2217,7 @@ MK_VIII::VoicePlayer::init () SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("avionics", true); + _sgr->tie_to_listener(); make_voice(&voices.application_data_base_failed, "application-data-base-failed"); make_voice(&voices.bank_angle, "bank-angle"); diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx index f3b95c5e3..79f864c33 100644 --- a/src/Instrumentation/navradio.cxx +++ b/src/Instrumentation/navradio.cxx @@ -185,6 +185,7 @@ FGNavRadio::init () { SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); _sgr = smgr->find("avionics", true); + _sgr->tie_to_listener(); morse.init(); From 33e816abb938b45baf148748a34ac9cef573ce04 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 7 Oct 2009 20:56:24 +0000 Subject: [PATCH 06/62] Split up FGFX into a dedicated effects class (FGFX) and a sample queue class. Register the sample queue cass as 'queue' at the SoundManager and tie it to the listener position. --- src/Main/fg_commands.cxx | 17 +++--- src/Sound/Makefile.am | 3 +- src/Sound/fg_fx.cxx | 61 ++-------------------- src/Sound/fg_fx.hxx | 25 +-------- src/Sound/sample_queue.cxx | 104 +++++++++++++++++++++++++++++++++++++ src/Sound/sample_queue.hxx | 70 +++++++++++++++++++++++++ 6 files changed, 193 insertions(+), 87 deletions(-) create mode 100644 src/Sound/sample_queue.cxx create mode 100644 src/Sound/sample_queue.hxx diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index ab6a15844..52b892a41 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -34,7 +34,7 @@ #include <Scenery/tilemgr.hxx> #include <Scenery/scenery.hxx> #include <Scripting/NasalSys.hxx> -#include <Sound/fg_fx.hxx> +#include <Sound/sample_queue.hxx> #include <Time/sunsolver.hxx> #include <Time/tmp.hxx> @@ -1254,15 +1254,20 @@ do_play_audio_sample (const SGPropertyNode * arg) { string path = arg->getStringValue("path"); string file = arg->getStringValue("file"); - double volume = arg->getDoubleValue("volume"); + float volume = arg->getFloatValue("volume"); // cout << "playing " << path << " / " << file << endl; try { - static FGFX *fx = 0; - if ( !fx ) { + static FGSampleQueue *queue = 0; + if ( !queue ) { SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); - fx = (FGFX *)smgr->find("fx"); + queue = new FGSampleQueue(smgr, "queue"); + queue->tie_to_listener(); } - if (fx) fx->play_message( path, file, volume ); + + SGSoundSample *msg = new SGSoundSample(path.c_str(), file.c_str()); + msg->set_volume( volume ); + queue->add( msg ); + return true; } catch (const sg_io_exception&) { diff --git a/src/Sound/Makefile.am b/src/Sound/Makefile.am index cbbb364f0..1512dd369 100644 --- a/src/Sound/Makefile.am +++ b/src/Sound/Makefile.am @@ -4,6 +4,7 @@ libSound_a_SOURCES = \ beacon.cxx beacon.hxx \ fg_fx.cxx fg_fx.hxx \ morse.cxx morse.hxx \ - voice.cxx voice.hxx + voice.cxx voice.hxx \ + sample_queue.cxx sample_queue.hxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index da6fcece3..6e06fa403 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -31,22 +31,14 @@ #include "fg_fx.hxx" -#include <simgear/debug/logstream.hxx> -#include <simgear/structure/exception.hxx> -#include <simgear/misc/sg_path.hxx> +#include <Main/fg_props.hxx> + #include <simgear/props/props.hxx> +#include <simgear/misc/sg_path.hxx> #include <simgear/sound/soundmgr_openal.hxx> #include <simgear/sound/xmlsound.hxx> -#include <Main/fg_props.hxx> - -#include <simgear/scene/model/placement.hxx> -#include <Model/acmodel.hxx> -#include <Main/viewer.hxx> - FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : - last_visitor_pos(SGVec3d::zeros()), - last_model_pos(SGVec3d::zeros()), last_pause( true ), last_volume( 0.0 ), _pause( fgGetNode("/sim/sound/pause") ), @@ -60,16 +52,10 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : FGFX::~FGFX () { - unsigned int i; - for ( i = 0; i < _sound.size(); i++ ) { + for (unsigned int i = 0; i < _sound.size(); i++ ) { delete _sound[i]; } _sound.clear(); - - while ( _samplequeue.size() > 0 ) { - delete _samplequeue.front(); - _samplequeue.pop(); - } } @@ -139,28 +125,6 @@ FGFX::update (double dt) last_pause = new_pause; } - // process mesage queue - const string msgid = "Sequential Audio Message"; - bool now_playing = false; - if ( exists( msgid ) ) { - if ( is_playing( msgid ) ) { - // still playing, do nothing - now_playing = true; - } else { - // current message finished, stop and remove - stop( msgid ); // removes source - remove( msgid ); // removes buffer - } - } - if ( !now_playing ) { - // message queue idle, add next sound if we have one - if ( _samplequeue.size() > 0 ) { - add( _samplequeue.front(), msgid ); - _samplequeue.pop(); - play_once( msgid ); - } - } - double volume = _volume->getDoubleValue(); if ( volume != last_volume ) { set_volume( volume ); @@ -177,21 +141,4 @@ FGFX::update (double dt) SGSampleGroup::update(dt); } -/** - * add a sound sample to the message queue which is played sequentially - * in order. - */ -void -FGFX::play_message( SGSoundSample *_sample ) -{ - _samplequeue.push( _sample ); -} -void -FGFX::play_message( const std::string& path, const std::string& fname, double volume ) -{ - SGSoundSample *sample = new SGSoundSample( path.c_str(), fname.c_str() ); - sample->set_volume( volume ); - play_message( sample ); -} - // end of fg_fx.cxx diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index 76d38915f..62e111076 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -26,12 +26,10 @@ #include <simgear/compiler.h> -#include <queue> #include <vector> #include <simgear/structure/subsystem_mgr.hxx> #include <simgear/sound/sample_group.hxx> -#include <simgear/math/SGMath.hxx> class SGXmlSound; @@ -39,17 +37,11 @@ class SGXmlSound; * Generator for FlightGear sound effects. * * This module uses a FGSampleGroup class to generate sound effects based - * on current flight conditions. The sound manager must be initialized + * on current flight conditions. The sound manager must be initialized * before this object is. * - * Note: this module supports two separate sound mechanisms concurrently. - * - * 1. This module will load and play a set of sound effects defined in an + * This module will load and play a set of sound effects defined in an * xml file and tie them to various property states. - * 2. This modules also maintains a queue of 'message' audio files. These - * are played sequentially with no overlap until the queue is finished. - * This second mechanims is useful for things like tutorial messages or - * background atc chatter. */ class FGFX : public SGSampleGroup { @@ -63,22 +55,9 @@ public: virtual void reinit (); virtual void update (double dt); - /** - * add a sound sample to the message queue which is played sequentially - * in order. - */ - void play_message( SGSoundSample *_sample ); - void play_message( const std::string& path, const std::string& fname, double volume ); - private: - void update_pos_and_orientation(double dt); - - SGVec3d last_visitor_pos; - SGVec3d last_model_pos; - std::vector<SGXmlSound *> _sound; - std::queue<SGSoundSample *> _samplequeue; bool last_pause; double last_volume; diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx new file mode 100644 index 000000000..30adf60df --- /dev/null +++ b/src/Sound/sample_queue.cxx @@ -0,0 +1,104 @@ +// _samplequeue.cxx -- Sound effect management class implementation +// +// Started by David Megginson, October 2001 +// (Reuses some code from main.cxx, probably by Curtis Olson) +// +// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifdef _MSC_VER +#pragma warning (disable: 4786) +#endif + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "sample_queue.hxx" + +#include <Main/fg_props.hxx> + +#include <simgear/sound/soundmgr_openal.hxx> +#include <simgear/sound/sample_openal.hxx> + +FGSampleQueue::FGSampleQueue ( SGSoundMgr *smgr, const string &refname ) : + last_pause( true ), + last_volume( 0.0 ), + _pause( fgGetNode("/sim/sound/pause") ), + _volume( fgGetNode("/sim/sound/volume") ) +{ + SGSampleGroup::_smgr = smgr; + SGSampleGroup::_smgr->add(this, refname); + SGSampleGroup::_active = _smgr->is_working(); +} + + +FGSampleQueue::~FGSampleQueue () +{ + while ( _messages.size() > 0 ) { + delete _messages.front(); + _messages.pop(); + } +} + + +void +FGSampleQueue::update (double dt) +{ + // command sound manger + bool new_pause = _pause->getBoolValue(); + if ( new_pause != last_pause ) { + if ( new_pause ) { + suspend(); + } else { + resume(); + } + last_pause = new_pause; + } + + double volume = _volume->getDoubleValue(); + if ( volume != last_volume ) { + set_volume( volume ); + last_volume = volume; + } + + // process mesage queue + const string msgid = "Sequential Audio Message"; + bool now_playing = false; + if ( exists( msgid ) ) { + now_playing = is_playing( msgid ); + if ( !now_playing ) { + // current message finished, stop and remove + stop( msgid ); // removes source + remove( msgid ); // removes buffer + } + } + + if ( !now_playing ) { + // message queue idle, add next sound if we have one + if ( _messages.size() > 0 ) { + SGSampleGroup::add( _messages.front(), msgid ); + _messages.pop(); + play_once( msgid ); + } + } + + SGSampleGroup::update(dt); +} + +// end of _samplequeue.cxx diff --git a/src/Sound/sample_queue.hxx b/src/Sound/sample_queue.hxx new file mode 100644 index 000000000..c874ae3eb --- /dev/null +++ b/src/Sound/sample_queue.hxx @@ -0,0 +1,70 @@ +// sample_queue.hxx -- sample queue management class +// +// Started by David Megginson, October 2001 +// (Reuses some code from main.cxx, probably by Curtis Olson) +// +// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifndef __FGSAMPLE_QUEUE_HXX +#define __FGSAMPLE_QUEUE_HXX 1 + +#include <simgear/compiler.h> + +#include <queue> + +#include <simgear/structure/subsystem_mgr.hxx> +#include <simgear/sound/sample_group.hxx> + +class SGSoundSample; + +/** + * FlightGear sample queue class + * + * This modules maintains a queue of 'message' audio files. These + * are played sequentially with no overlap until the queue is finished. + * This second mechanims is useful for things like tutorial messages or + * background atc chatter. + */ +class FGSampleQueue : public SGSampleGroup +{ + +public: + + FGSampleQueue ( SGSoundMgr *smgr, const string &refname ); + virtual ~FGSampleQueue (); + + virtual void update (double dt); + + inline void add (SGSoundSample *msg) { _messages.push(msg); } + +private: + + std::queue<SGSoundSample *> _messages; + + bool last_pause; + double last_volume; + + SGPropertyNode_ptr _pause; + SGPropertyNode_ptr _volume; +}; + + +#endif + +// end of fg_fx.hxx From b582c118bd6bba58a32d75d2d8ef45b612b231d3 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 11 Oct 2009 13:40:12 +0000 Subject: [PATCH 07/62] Correct (and verrified) position, orientation and velocity vector. Todo: proper sound orientation (the all face forward using the airplane orientation now) and disabling doppler effect when tied to the listener --- src/Main/viewmgr.cxx | 28 ++++++++++++++++++++++------ src/Main/viewmgr.hxx | 1 + src/Model/acmodel.cxx | 14 +++++--------- src/Model/acmodel.hxx | 1 - src/Sound/fg_fx.cxx | 1 + 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index d429c219c..18b16a6a2 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -248,7 +248,6 @@ FGViewMgr::update (double dt) FGViewer *loop_view = (FGViewer *)get_view(current); SGPropertyNode *n = config_list[current]; double lon_deg, lat_deg, alt_ft, roll_deg, pitch_deg, heading_deg; - SGVec3f velocity = SGVec3f(0,0,0); // Set up view location and orientation @@ -265,10 +264,6 @@ FGViewMgr::update (double dt) } else { // force recalc in viewer loop_view->set_dirty(); - - // get the model velocity for the in-cockpit view - FGAircraftModel *aircraft = globals->get_aircraft_model(); - velocity = aircraft->getVelocity(); } // if lookat (type 1) then get target data... @@ -303,8 +298,15 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position(abs_viewer_position); + smgr->set_position(-abs_viewer_position); smgr->set_orientation(loop_view->getViewOrientation()); + + // get the model velocity for the in-cockpit view + SGVec3f velocity = SGVec3f(0,0,0); + if ( !stationary() ) { + FGAircraftModel *aircraft = globals->get_aircraft_model(); + velocity = aircraft->getVelocity(); + } smgr->set_velocity(velocity); } @@ -575,6 +577,20 @@ FGViewMgr::setViewZOffset_m (double z) } } +bool +FGViewMgr::stationary () const +{ + const FGViewer * view = get_current_view(); + if (view != 0) { + if (((FGViewer *)view)->getXOffset_m() == 0.0 && + ((FGViewer *)view)->getYOffset_m() == 0.0 && + ((FGViewer *)view)->getZOffset_m() == 0.0) + return true; + } + + return false; +} + double FGViewMgr::getViewTargetXOffset_m () const { diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 76ede702e..2c0feb428 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -116,6 +116,7 @@ private: void setViewAxisLat (double axis); int getView () const; void setView (int newview); + bool stationary () const; SGPropertyNode_ptr view_number; vector<SGPropertyNode_ptr> config_list; diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 0541a1159..ff2c81aa0 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -44,8 +44,7 @@ FGAircraftModel::FGAircraftModel () _pitch(0), _roll(0), _heading(0), - _speed(0), - _speed_up(0) + _speed(0) { SGSoundMgr *smgr; smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); @@ -92,8 +91,7 @@ FGAircraftModel::bind () _pitch = fgGetNode("orientation/pitch-deg", true); _roll = fgGetNode("orientation/roll-deg", true); _heading = fgGetNode("orientation/heading-deg", true); - _speed = fgGetNode("velocities/true-airspeed-kt", true); - _speed_up = fgGetNode("velocities/vertical-speed-fps", true); + _speed = fgGetNode("velocities/groundspeed-kt", true); } void @@ -125,21 +123,19 @@ FGAircraftModel::update (double dt) // update model's audio sample values // Get the Cartesian coordinates in meters SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); - _fx->set_position( pos ); + _fx->set_position( -pos ); SGQuatd orient_m = SGQuatd::fromLonLat(_aircraft->getPosition()); orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), _pitch->getDoubleValue(), _roll->getDoubleValue()); SGVec3d orient = -orient_m.rotate(SGVec3d::e1()); - _fx->set_orientation( toVec3f(orient) ); + _fx->set_orientation( toVec3f( orient ) ); // For now assume the aircraft speed is always along the longitudinal // axis, so sideslipping is not taken into account. This should be fine // for audio. - _velocity = toVec3f(orient * _speed->getDoubleValue() * SG_KT_TO_FPS); - // _velocity[2] = _speed_up->getFloatValue(); - _velocity *= SG_FEET_TO_METER; + _velocity = toVec3f(orient * _speed->getDoubleValue() * SG_KT_TO_MPS); _fx->set_velocity( _velocity ); } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index 5a0b31a0e..dd6e3b01f 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -54,7 +54,6 @@ private: SGPropertyNode * _roll; SGPropertyNode * _heading; SGPropertyNode * _speed; - SGPropertyNode * _speed_up; }; diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 6e06fa403..934ec5c1a 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -45,6 +45,7 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : _volume( fgGetNode("/sim/sound/volume") ) { SGSampleGroup::_smgr = smgr; + SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); SGSampleGroup::_active = _smgr->is_working(); } From a9b3fc7a561a7e809df84ac9ed79d117016f3dcf Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 15 Oct 2009 09:20:03 +0000 Subject: [PATCH 08/62] move some of the sound postion and orientation calculations over to the sample class which also makes the main code nice and clean --- src/Instrumentation/mk_viii.cxx | 15 --------------- src/Instrumentation/mk_viii.hxx | 14 -------------- src/Main/viewmgr.cxx | 4 ++-- src/Model/acmodel.cxx | 31 +++++++++++++++---------------- src/Model/acmodel.hxx | 9 +++++---- 5 files changed, 22 insertions(+), 51 deletions(-) diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index e484127f7..340c4bf11 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2106,16 +2106,6 @@ MK_VIII::VoicePlayer::Speaker::bind (SGPropertyNode *node) // uses xmlsound property names tie(node, "volume", &volume); tie(node, "pitch", &pitch); - tie(node, "position/x", &position[0]); - tie(node, "position/y", &position[1]); - tie(node, "position/z", &position[2]); - tie(node, "orientation/x", &orientation[0]); - tie(node, "orientation/y", &orientation[1]); - tie(node, "orientation/z", &orientation[2]); - tie(node, "orientation/inner-cone", &inner_cone); - tie(node, "orientation/outer-cone", &outer_cone); - tie(node, "reference-dist", &reference_dist); - tie(node, "max-dist", &max_dist); } void @@ -2127,11 +2117,6 @@ MK_VIII::VoicePlayer::Speaker::update_configuration () SGSoundSample *sample = (*iter).second; sample->set_pitch(pitch); - sample->set_base_position(position); // TODO: tie to listener pos - sample->set_orientation(orientation); - sample->set_audio_cone(inner_cone, outer_cone, outer_gain); - sample->set_reference_dist(reference_dist); - sample->set_max_dist(max_dist); } if (player->voice) diff --git a/src/Instrumentation/mk_viii.hxx b/src/Instrumentation/mk_viii.hxx index 27cf023fa..077ea52ab 100755 --- a/src/Instrumentation/mk_viii.hxx +++ b/src/Instrumentation/mk_viii.hxx @@ -889,13 +889,6 @@ public: VoicePlayer *player; double pitch; - SGVec3d position; - SGVec3f orientation; - float inner_cone; - float outer_cone; - float outer_gain; - float reference_dist; - float max_dist; template <class T> inline void tie (SGPropertyNode *node, const char *name, T *ptr) @@ -920,15 +913,8 @@ public: inline Speaker (VoicePlayer *_player) : player(_player), pitch(1), - inner_cone(360), - outer_cone(360), - outer_gain(0), - reference_dist(3), - max_dist(10), volume(1) { - position[0] = 0; position[1] = 0; position[2] = 0; - orientation[0] = 0; orientation[1] = 0; orientation[2] = 0; } void bind (SGPropertyNode *node); diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 18b16a6a2..a23a28d79 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -298,11 +298,11 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position(-abs_viewer_position); + smgr->set_position( abs_viewer_position ); smgr->set_orientation(loop_view->getViewOrientation()); // get the model velocity for the in-cockpit view - SGVec3f velocity = SGVec3f(0,0,0); + SGVec3d velocity = SGVec3d(0,0,0); if ( !stationary() ) { FGAircraftModel *aircraft = globals->get_aircraft_model(); velocity = aircraft->getVelocity(); diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index ff2c81aa0..b4fda2e87 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -36,7 +36,7 @@ FGAircraftModel::FGAircraftModel () : _aircraft(0), - _velocity(SGVec3f::zeros()), + _velocity(SGVec3d::zeros()), _fx(0), _lon(0), _lat(0), @@ -44,7 +44,9 @@ FGAircraftModel::FGAircraftModel () _pitch(0), _roll(0), _heading(0), - _speed(0) + _speed_n(0), + _speed_e(0), + _speed_d(0) { SGSoundMgr *smgr; smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); @@ -91,7 +93,9 @@ FGAircraftModel::bind () _pitch = fgGetNode("orientation/pitch-deg", true); _roll = fgGetNode("orientation/roll-deg", true); _heading = fgGetNode("orientation/heading-deg", true); - _speed = fgGetNode("velocities/groundspeed-kt", true); + _speed_n = fgGetNode("velocities/speed-north-fps", true); + _speed_e = fgGetNode("velocities/speed-east-fps", true); + _speed_d = fgGetNode("velocities/speed-down-fps", true); } void @@ -121,21 +125,16 @@ FGAircraftModel::update (double dt) _aircraft->update(); // update model's audio sample values - // Get the Cartesian coordinates in meters - SGVec3d pos = SGVec3d::fromGeod(_aircraft->getPosition()); - _fx->set_position( -pos ); + _fx->set_position( _aircraft->getPosition() ); - SGQuatd orient_m = SGQuatd::fromLonLat(_aircraft->getPosition()); - orient_m *= SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), - _pitch->getDoubleValue(), - _roll->getDoubleValue()); - SGVec3d orient = -orient_m.rotate(SGVec3d::e1()); - _fx->set_orientation( toVec3f( orient ) ); + SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), + _pitch->getDoubleValue(), + _roll->getDoubleValue()); + _fx->set_orientation( orient ); - // For now assume the aircraft speed is always along the longitudinal - // axis, so sideslipping is not taken into account. This should be fine - // for audio. - _velocity = toVec3f(orient * _speed->getDoubleValue() * SG_KT_TO_MPS); + _velocity = SGVec3d( -_speed_n->getDoubleValue(), + -_speed_e->getDoubleValue(), + -_speed_d->getDoubleValue()); _fx->set_velocity( _velocity ); } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index dd6e3b01f..c751b699c 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -39,12 +39,12 @@ public: virtual void unbind (); virtual void update (double dt); virtual SGModelPlacement * get3DModel() { return _aircraft; } - virtual SGVec3f getVelocity() { return _velocity; } + virtual SGVec3d getVelocity() { return _velocity; } private: SGModelPlacement * _aircraft; - SGVec3f _velocity; + SGVec3d _velocity; FGFX * _fx; SGPropertyNode * _lon; @@ -53,8 +53,9 @@ private: SGPropertyNode * _pitch; SGPropertyNode * _roll; SGPropertyNode * _heading; - SGPropertyNode * _speed; - + SGPropertyNode * _speed_n; + SGPropertyNode * _speed_e; + SGPropertyNode * _speed_d; }; #endif // __ACMODEL_HXX From 1b080515973ede0e74908888fcaec96bbe519319 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Fri, 16 Oct 2009 09:45:54 +0000 Subject: [PATCH 09/62] SoundManager fixes --- src/Model/acmodel.cxx | 4 ++-- src/Sound/fg_fx.cxx | 1 - src/Sound/sample_queue.cxx | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index b4fda2e87..318b082e9 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -128,8 +128,8 @@ FGAircraftModel::update (double dt) _fx->set_position( _aircraft->getPosition() ); SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), - _pitch->getDoubleValue(), - _roll->getDoubleValue()); + _pitch->getDoubleValue(), + _roll->getDoubleValue()); _fx->set_orientation( orient ); _velocity = SGVec3d( -_speed_n->getDoubleValue(), diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 934ec5c1a..8bc493bfa 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -47,7 +47,6 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : SGSampleGroup::_smgr = smgr; SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); - SGSampleGroup::_active = _smgr->is_working(); } diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx index 30adf60df..d032a8d90 100644 --- a/src/Sound/sample_queue.cxx +++ b/src/Sound/sample_queue.cxx @@ -44,7 +44,6 @@ FGSampleQueue::FGSampleQueue ( SGSoundMgr *smgr, const string &refname ) : { SGSampleGroup::_smgr = smgr; SGSampleGroup::_smgr->add(this, refname); - SGSampleGroup::_active = _smgr->is_working(); } From 78aa4be170b61b26e4f2fcb899413700b2c6cac4 Mon Sep 17 00:00:00 2001 From: frohlich <frohlich> Date: Sat, 17 Oct 2009 19:21:26 +0000 Subject: [PATCH 10/62] Fix 64 bit linux builds. Modified Files: src/ATCDCL/ATCVoice.hxx --- src/ATCDCL/ATCVoice.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ATCDCL/ATCVoice.hxx b/src/ATCDCL/ATCVoice.hxx index 5da976848..f4b6c7f50 100644 --- a/src/ATCDCL/ATCVoice.hxx +++ b/src/ATCDCL/ATCVoice.hxx @@ -56,7 +56,7 @@ private: // the sound and word position data char* rawSoundData; - unsigned int rawDataSize; + size_t rawDataSize; SGSoundSample *SoundData; // A map of words vs. byte position and length in rawSoundData From 73d4b78396064439237135d5d4b3b8e793cb5e4e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 18 Oct 2009 13:45:01 +0000 Subject: [PATCH 11/62] explicitly activate the sound manager --- src/Main/main.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 91e1542db..30741f1c1 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -492,10 +492,12 @@ static void fgMainLoop( void ) { && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); #ifdef ENABLE_AUDIO_SUPPORT - if (fgGetBool("/sim/sound/enabled") == false) - smgr->stop(); - else + if (fgGetBool("/sim/sound/enabled") == true) { smgr->set_volume(fgGetFloat("/sim/sound/volume")); + smgr->activate(); + } + else + smgr->stop(); #endif } From afb0ada81f6fd0fe179ab00f048134d101f5f311 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 19 Oct 2009 08:57:14 +0000 Subject: [PATCH 12/62] Make sure the unbind method is called for all registered subsystems proir to deleting the subsystem manager. --- src/Main/globals.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 84cf9c932..7e6553fa4 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -125,6 +125,7 @@ FGGlobals::~FGGlobals() // deleted subsystems. subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("input"); subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("gui"); + subsystem_mgr->unbind(); delete subsystem_mgr; delete event_mgr; delete time_params; From b25940e1ea03af325a8a3648e1f389d7a489b22e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 19 Oct 2009 10:41:17 +0000 Subject: [PATCH 13/62] Fix a number of small bugs; eg test if SoundMgr::load fails and return false in that case. --- src/ATCDCL/ATCVoice.cxx | 3 ++- src/Sound/fg_fx.cxx | 19 +++++++------- src/Sound/sample_queue.cxx | 51 ++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx index 023dde22c..bcd48f54a 100644 --- a/src/ATCDCL/ATCVoice.cxx +++ b/src/ATCDCL/ATCVoice.cxx @@ -74,7 +74,8 @@ bool FGATCVoice::LoadVoice(const string& voice) { int format, freq; SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); void *data; - smgr->load(full_path, &data, &format, &rawDataSize, &freq); + if (!smgr->load(full_path, &data, &format, &rawDataSize, &freq)) + return false; rawSoundData = (char*)data; #ifdef VOICE_TEST cout << "ATCVoice: format: " << format diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 8bc493bfa..4d879bff2 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -39,7 +39,7 @@ #include <simgear/sound/xmlsound.hxx> FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : - last_pause( true ), + last_pause( false ), last_volume( 0.0 ), _pause( fgGetNode("/sim/sound/pause") ), _volume( fgGetNode("/sim/sound/volume") ) @@ -114,7 +114,6 @@ FGFX::reinit() void FGFX::update (double dt) { - // command sound manger bool new_pause = _pause->getBoolValue(); if ( new_pause != last_pause ) { if ( new_pause ) { @@ -125,20 +124,20 @@ FGFX::update (double dt) last_pause = new_pause; } - double volume = _volume->getDoubleValue(); - if ( volume != last_volume ) { - set_volume( volume ); - last_volume = volume; - } - if ( !new_pause ) { + double volume = _volume->getDoubleValue(); + if ( volume != last_volume ) { + set_volume( volume ); + last_volume = volume; + } + // update sound effects if not paused for ( unsigned int i = 0; i < _sound.size(); i++ ) { _sound[i]->update(dt); } - } - SGSampleGroup::update(dt); + SGSampleGroup::update(dt); + } } // end of fg_fx.cxx diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx index d032a8d90..f09870947 100644 --- a/src/Sound/sample_queue.cxx +++ b/src/Sound/sample_queue.cxx @@ -37,7 +37,7 @@ #include <simgear/sound/sample_openal.hxx> FGSampleQueue::FGSampleQueue ( SGSoundMgr *smgr, const string &refname ) : - last_pause( true ), + last_pause( false ), last_volume( 0.0 ), _pause( fgGetNode("/sim/sound/pause") ), _volume( fgGetNode("/sim/sound/volume") ) @@ -59,6 +59,7 @@ FGSampleQueue::~FGSampleQueue () void FGSampleQueue::update (double dt) { +return; // command sound manger bool new_pause = _pause->getBoolValue(); if ( new_pause != last_pause ) { @@ -70,34 +71,36 @@ FGSampleQueue::update (double dt) last_pause = new_pause; } - double volume = _volume->getDoubleValue(); - if ( volume != last_volume ) { - set_volume( volume ); - last_volume = volume; - } + if ( !new_pause ) { + double volume = _volume->getDoubleValue(); + if ( volume != last_volume ) { + set_volume( volume ); + last_volume = volume; + } + + // process mesage queue + const string msgid = "Sequential Audio Message"; + bool now_playing = false; + if ( exists( msgid ) ) { + now_playing = is_playing( msgid ); + if ( !now_playing ) { + // current message finished, stop and remove + stop( msgid ); // removes source + remove( msgid ); // removes buffer + } + } - // process mesage queue - const string msgid = "Sequential Audio Message"; - bool now_playing = false; - if ( exists( msgid ) ) { - now_playing = is_playing( msgid ); if ( !now_playing ) { - // current message finished, stop and remove - stop( msgid ); // removes source - remove( msgid ); // removes buffer + // message queue idle, add next sound if we have one + if ( _messages.size() > 0 ) { + SGSampleGroup::add( _messages.front(), msgid ); + _messages.pop(); + play_once( msgid ); + } } - } - if ( !now_playing ) { - // message queue idle, add next sound if we have one - if ( _messages.size() > 0 ) { - SGSampleGroup::add( _messages.front(), msgid ); - _messages.pop(); - play_once( msgid ); - } + SGSampleGroup::update(dt); } - - SGSampleGroup::update(dt); } // end of _samplequeue.cxx From 7d6631d9a65c32b4c86792c5e2d9b998c7ebb48e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 19 Oct 2009 11:08:27 +0000 Subject: [PATCH 14/62] remove a debugging left-over --- src/Sound/sample_queue.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx index f09870947..9d7140165 100644 --- a/src/Sound/sample_queue.cxx +++ b/src/Sound/sample_queue.cxx @@ -59,7 +59,6 @@ FGSampleQueue::~FGSampleQueue () void FGSampleQueue::update (double dt) { -return; // command sound manger bool new_pause = _pause->getBoolValue(); if ( new_pause != last_pause ) { From e2678830bab0472cb92ec280d89fbfbdc665b89f Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 19 Oct 2009 14:10:31 +0000 Subject: [PATCH 15/62] Use auto_ptr when calling SGSoundSample --- src/ATCDCL/ATC.cxx | 4 +++- src/Sound/beacon.cxx | 12 ++++++------ src/Sound/morse.cxx | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 92568edc5..480257bc7 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -237,8 +237,10 @@ void FGATC::Render(string& msg, const float volume, // >>> Beware: must pass a (new) object to the (add) method, // >>> because the (remove) method is going to do a (delete) // >>> whether that's what you want or not. + std::auto_ptr<unsigned char> ptr; + ptr.reset((unsigned char*) buf.c_str()); SGSoundSample *simple = - new SGSoundSample((unsigned char*) buf.c_str(), buf.length(), 8000); + new SGSoundSample(ptr, buf.length(), 8000); // TODO - at the moment the volume can't be changed // after the transmission has started. simple->set_volume(volume); diff --git a/src/Sound/beacon.cxx b/src/Sound/beacon.cxx index 9b5f353af..6de5f4624 100644 --- a/src/Sound/beacon.cxx +++ b/src/Sound/beacon.cxx @@ -41,9 +41,9 @@ bool FGBeacon::init() { int len; unsigned char *ptr; - unsigned char *inner_buf = new unsigned char[ INNER_SIZE ] ; - unsigned char *middle_buf = new unsigned char[ MIDDLE_SIZE ] ; - unsigned char *outer_buf = new unsigned char[ OUTER_SIZE ] ; + std::auto_ptr<unsigned char>inner_buf( new unsigned char[ INNER_SIZE ] ); + std::auto_ptr<unsigned char>middle_buf( new unsigned char[ MIDDLE_SIZE ] ); + std::auto_ptr<unsigned char>outer_buf( new unsigned char[ OUTER_SIZE ] ); // Make inner marker beacon sound len= (int)(INNER_DIT_LEN / 2.0 ); @@ -51,7 +51,7 @@ bool FGBeacon::init() { make_tone( inner_dit, INNER_FREQ, len, INNER_DIT_LEN, TRANSITION_BYTES ); - ptr = inner_buf; + ptr = inner_buf.get(); for ( i = 0; i < 6; ++i ) { memcpy( ptr, inner_dit, INNER_DIT_LEN ); ptr += INNER_DIT_LEN; @@ -73,7 +73,7 @@ bool FGBeacon::init() { make_tone( middle_dah, MIDDLE_FREQ, len, MIDDLE_DAH_LEN, TRANSITION_BYTES ); - ptr = middle_buf; + ptr = middle_buf.get(); memcpy( ptr, middle_dit, MIDDLE_DIT_LEN ); ptr += MIDDLE_DIT_LEN; memcpy( ptr, middle_dah, MIDDLE_DAH_LEN ); @@ -88,7 +88,7 @@ bool FGBeacon::init() { make_tone( outer_dah, OUTER_FREQ, len, OUTER_DAH_LEN, TRANSITION_BYTES ); - ptr = outer_buf; + ptr = outer_buf.get(); memcpy( ptr, outer_dah, OUTER_DAH_LEN ); ptr += OUTER_DAH_LEN; memcpy( ptr, outer_dah, OUTER_DAH_LEN ); diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx index a56273288..c9195e78d 100644 --- a/src/Sound/morse.cxx +++ b/src/Sound/morse.cxx @@ -219,10 +219,10 @@ SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) { length += 2 * SPACE_SIZE; // 2. Allocate space for the message - unsigned char *buffer = new unsigned char[length]; + std::auto_ptr<unsigned char>buffer( new unsigned char[length] ); // 3. Assemble the message; - unsigned char *buf_ptr = buffer; + unsigned char *buf_ptr = buffer.get(); for ( i = 0; i < (int)id.length(); ++i ) { if ( idptr[i] >= 'A' && idptr[i] <= 'Z' ) { From 6e2974ea570da0f6d4d671b2410bea1383fc630c Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 20 Oct 2009 11:31:42 +0000 Subject: [PATCH 16/62] Assorted small soundsystem related fixes. --- src/ATCDCL/AIPlane.cxx | 4 +++- src/ATCDCL/ATC.cxx | 4 ++-- src/Sound/beacon.cxx | 2 ++ src/Sound/morse.cxx | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index eecc070d9..0706fe367 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -24,6 +24,7 @@ #include <simgear/sound/soundmgr_openal.hxx> #include <math.h> #include <string> +#include <memory> using std::string; @@ -200,8 +201,9 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating if(voice) { string buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice); if(voice && (volume > 0.05)) { + std::auto_ptr<unsigned char> ptr( buf.c_str() ); SGSoundSample* simple = - new SGSoundSample((unsigned char*)buf.c_str(), buf.length(), 8000 ); + new SGSoundSample(ptr, buf.length(), 8000 ); // TODO - at the moment the volume can't be changed // after the transmission has started. simple->set_volume(volume); diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 480257bc7..9a8d16028 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -25,6 +25,7 @@ #include "ATC.hxx" #include <iostream> +#include <memory> #include <simgear/sound/soundmgr_openal.hxx> #include <simgear/structure/exception.hxx> @@ -237,8 +238,7 @@ void FGATC::Render(string& msg, const float volume, // >>> Beware: must pass a (new) object to the (add) method, // >>> because the (remove) method is going to do a (delete) // >>> whether that's what you want or not. - std::auto_ptr<unsigned char> ptr; - ptr.reset((unsigned char*) buf.c_str()); + std::auto_ptr<unsigned char> ptr( (unsigned char*)buf.c_str() ); SGSoundSample *simple = new SGSoundSample(ptr, buf.length(), 8000); // TODO - at the moment the volume can't be changed diff --git a/src/Sound/beacon.cxx b/src/Sound/beacon.cxx index 6de5f4624..497cbf032 100644 --- a/src/Sound/beacon.cxx +++ b/src/Sound/beacon.cxx @@ -21,6 +21,8 @@ // $Id$ +#include <memory> + #include "beacon.hxx" #include <simgear/structure/exception.hxx> diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx index c9195e78d..0943b8a86 100644 --- a/src/Sound/morse.cxx +++ b/src/Sound/morse.cxx @@ -21,6 +21,8 @@ // $Id$ +#include <memory> + #include <simgear/constants.h> #include "morse.hxx" From 42b990ca1b5f2916b72e699308ca8747b1332e19 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 22 Oct 2009 11:51:15 +0000 Subject: [PATCH 17/62] line up aircraft orientation and velocity vector --- src/Model/acmodel.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 318b082e9..1dcf2bd22 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -133,8 +133,8 @@ FGAircraftModel::update (double dt) _fx->set_orientation( orient ); _velocity = SGVec3d( -_speed_n->getDoubleValue(), - -_speed_e->getDoubleValue(), - -_speed_d->getDoubleValue()); + _speed_e->getDoubleValue(), + _speed_d->getDoubleValue()); _fx->set_velocity( _velocity ); } From 9c8d6ee663c5b3aabc9019bd538230bb46338596 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 22 Oct 2009 12:53:48 +0000 Subject: [PATCH 18/62] Add a proper typecast --- src/ATCDCL/AIPlane.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 0706fe367..1a3e77dc0 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -201,7 +201,7 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating if(voice) { string buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice); if(voice && (volume > 0.05)) { - std::auto_ptr<unsigned char> ptr( buf.c_str() ); + std::auto_ptr<unsigned char> ptr( (unsigned char*)buf.c_str() ); SGSoundSample* simple = new SGSoundSample(ptr, buf.length(), 8000 ); // TODO - at the moment the volume can't be changed From f9445874a02689cbd9a0197c5aac7ffeab1436ac Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sat, 24 Oct 2009 08:31:37 +0000 Subject: [PATCH 19/62] Don't make the SoundManager a memebr of the subsystem manager; It needs to be initialized very early and destroyed as late as possible. That doesn't work as a subsystem meber onless some sort of priority scheme gets implemented. Get rid of auto_ptr which doesn work for the samples either. --- src/ATCDCL/AIPlane.cxx | 13 ++++--------- src/ATCDCL/ATC.cxx | 15 +++++---------- src/ATCDCL/ATCVoice.cxx | 22 ++++++++++++---------- src/ATCDCL/ATCVoice.hxx | 4 ++-- src/Environment/fgclouds.cxx | 2 +- src/Instrumentation/adf.cxx | 2 +- src/Instrumentation/kr_87.cxx | 2 +- src/Instrumentation/marker_beacon.cxx | 2 +- src/Instrumentation/mk_viii.cxx | 2 +- src/Instrumentation/navradio.cxx | 2 +- src/Main/fg_commands.cxx | 2 +- src/Main/fg_init.cxx | 7 +++++++ src/Main/fg_props.cxx | 2 +- src/Main/globals.cxx | 14 ++++++++++++-- src/Main/globals.hxx | 4 ++++ src/Main/main.cxx | 9 +-------- src/Main/viewmgr.cxx | 2 +- src/Model/acmodel.cxx | 3 +-- src/Sound/beacon.cxx | 23 +++++++++++------------ src/Sound/morse.cxx | 8 +++----- 20 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 1a3e77dc0..3a46ee051 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -24,7 +24,6 @@ #include <simgear/sound/soundmgr_openal.hxx> #include <math.h> #include <string> -#include <memory> using std::string; @@ -52,8 +51,7 @@ FGAIPlane::FGAIPlane() { _rollSuspended = false; if ( !_sgr ) { - SGSoundMgr *smgr; - smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("atc", true); _sgr->tie_to_listener(); } @@ -199,13 +197,10 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating #ifdef ENABLE_AUDIO_SUPPORT voice = (voiceOK && fgGetBool("/sim/sound/voice")); if(voice) { - string buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice); + sizte_t len; + void* buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice, &len); if(voice && (volume > 0.05)) { - std::auto_ptr<unsigned char> ptr( (unsigned char*)buf.c_str() ); - SGSoundSample* simple = - new SGSoundSample(ptr, buf.length(), 8000 ); - // TODO - at the moment the volume can't be changed - // after the transmission has started. + SGSoundSample* simple = new SGSoundSample(buf, len, 8000 ); simple->set_volume(volume); _sgr->add(simple, refname); _sgr->play(refname, repeating); diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 9a8d16028..7e17f1da7 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -25,7 +25,6 @@ #include "ATC.hxx" #include <iostream> -#include <memory> #include <simgear/sound/soundmgr_openal.hxx> #include <simgear/structure/exception.hxx> @@ -57,8 +56,7 @@ FGATC::FGATC() : _counter(0.0), _max_count(5.0) { - SGSoundMgr *smgr; - smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("atc", true); } @@ -231,18 +229,15 @@ void FGATC::Render(string& msg, const float volume, #ifdef ENABLE_AUDIO_SUPPORT _voice = (_voiceOK && fgGetBool("/sim/sound/voice")); if(_voice) { - string buf = _vPtr->WriteMessage((char*)msg.c_str(), _voice); - if(_voice && (volume > 0.05)) { + size_t len; + void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len); + if(buf && (volume > 0.05)) { NoRender(refname); try { // >>> Beware: must pass a (new) object to the (add) method, // >>> because the (remove) method is going to do a (delete) // >>> whether that's what you want or not. - std::auto_ptr<unsigned char> ptr( (unsigned char*)buf.c_str() ); - SGSoundSample *simple = - new SGSoundSample(ptr, buf.length(), 8000); - // TODO - at the moment the volume can't be changed - // after the transmission has started. + SGSoundSample *simple = new SGSoundSample(&buf, len, 8000); simple->set_volume(volume); _sgr->add(simple, refname); _sgr->play(refname, repeating); diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx index bcd48f54a..5659b1132 100644 --- a/src/ATCDCL/ATCVoice.cxx +++ b/src/ATCDCL/ATCVoice.cxx @@ -72,7 +72,7 @@ bool FGATCVoice::LoadVoice(const string& voice) { string full_path = path.str(); int format, freq; - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); void *data; if (!smgr->load(full_path, &data, &format, &rawDataSize, &freq)) return false; @@ -134,7 +134,7 @@ typedef tokenList_type::iterator tokenList_iterator; // Given a desired message, return a string containing the // sound-sample data -string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { +void* FGATCVoice::WriteMessage(const char* message, size_t* len) { // What should we do here? // First - parse the message into a list of tokens. @@ -185,8 +185,8 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { // Check for no tokens found else slScheduler can be crashed if(!word) { - dataOK = false; - return ""; + *len = 0; + return NULL; } boost::shared_array<char> tmpbuf(new char[cumLength]); unsigned int bufpos = 0; @@ -202,8 +202,8 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { SG_LOG(SG_ATC, SG_ALERT, "Offset + length: " << wdptr[i].offset + wdptr[i].length << " exceeds rawdata size: " << rawDataSize << endl); - dataOK = false; - return ""; + *len = 0; + return NULL; } memcpy(tmpbuf.get() + bufpos, rawSoundData + wdptr[i].offset, wdptr[i].length); bufpos += wdptr[i].length; @@ -213,9 +213,11 @@ string FGATCVoice::WriteMessage(const char* message, bool& dataOK) { unsigned int offsetIn = (int)(cumLength * sg_random()); if(offsetIn > cumLength) offsetIn = cumLength; - string front(tmpbuf.get(), offsetIn); - string back(tmpbuf.get() + offsetIn, cumLength - offsetIn); + void *data = malloc(cumLength); + memcpy(data, tmpbuf.get(), cumLength); + *len = cumLength; + // string front(tmpbuf.get(), offsetIn); + // string back(tmpbuf.get() + offsetIn, cumLength - offsetIn); - dataOK = true; - return back + front; + return data; } diff --git a/src/ATCDCL/ATCVoice.hxx b/src/ATCDCL/ATCVoice.hxx index f4b6c7f50..6ec4f3932 100644 --- a/src/ATCDCL/ATCVoice.hxx +++ b/src/ATCDCL/ATCVoice.hxx @@ -49,8 +49,8 @@ public: bool LoadVoice(const std::string& voice); // Given a desired message, return a pointer to the data buffer and write the buffer length into len. - // Sets dataOK = true if the returned buffer is valid. - std::string WriteMessage(const char* message, bool& dataOK); + // Sets len to something other than 0 if the returned buffer is valid. + void* WriteMessage(const char* message, size_t *len); private: diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index a4264bc58..1498a00f4 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -68,7 +68,7 @@ void FGClouds::init(void) { snd_lightning = new SGSoundSample(globals->get_fg_root().c_str(), "Sounds/thunder.wav"); snd_lightning->set_max_dist(7000.0f); snd_lightning->set_reference_dist(3000.0f); - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); SGSampleGroup *sgr = smgr->find("weather", true); sgr->add( snd_lightning, "thunder" ); sgEnviro.set_sampleGroup( sgr ); diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx index 9f9ba2d83..6da2a2ed4 100644 --- a/src/Instrumentation/adf.cxx +++ b/src/Instrumentation/adf.cxx @@ -102,7 +102,7 @@ ADF::init () _ident_node = node->getChild("ident", 0, true); _ident_audible_node = node->getChild("ident-audible", 0, true); - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); _sgr->tie_to_listener(); diff --git a/src/Instrumentation/kr_87.cxx b/src/Instrumentation/kr_87.cxx index d0087c098..41928a097 100644 --- a/src/Instrumentation/kr_87.cxx +++ b/src/Instrumentation/kr_87.cxx @@ -117,7 +117,7 @@ FGKR_87::~FGKR_87() { void FGKR_87::init () { - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); _sgr->tie_to_listener(); morse.init(); diff --git a/src/Instrumentation/marker_beacon.cxx b/src/Instrumentation/marker_beacon.cxx index 3a0d33819..d2e9774b7 100644 --- a/src/Instrumentation/marker_beacon.cxx +++ b/src/Instrumentation/marker_beacon.cxx @@ -117,7 +117,7 @@ FGMarkerBeacon::init () if (serviceable->getType() == simgear::props::NONE) serviceable->setBoolValue( true ); - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); _sgr->tie_to_listener(); diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index 340c4bf11..f2a4dba2c 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2200,7 +2200,7 @@ MK_VIII::VoicePlayer::init () { #define STDPAUSE 0.75 // [SPEC] 6.4.4: "the standard 0.75 second delay" - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); _sgr->tie_to_listener(); diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx index 79f864c33..4dace88a0 100644 --- a/src/Instrumentation/navradio.cxx +++ b/src/Instrumentation/navradio.cxx @@ -183,7 +183,7 @@ FGNavRadio::~FGNavRadio() void FGNavRadio::init () { - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); _sgr->tie_to_listener(); diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 52b892a41..151efa207 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -1259,7 +1259,7 @@ do_play_audio_sample (const SGPropertyNode * arg) try { static FGSampleQueue *queue = 0; if ( !queue ) { - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); queue = new FGSampleQueue(smgr, "queue"); queue->tie_to_listener(); } diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index a78759c42..cf6c86b70 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1448,6 +1448,13 @@ bool fgInitSubsystems() { globals->get_event_mgr()->init(); globals->get_event_mgr()->setRealtimeProperty(fgGetNode("/sim/time/delta-realtime-sec", true)); + //////////////////////////////////////////////////////////////////// + // Initialize the sound manager subsystem. + //////////////////////////////////////////////////////////////////// + + globals->get_soundmgr()->bind(); + globals->get_soundmgr()->init(); + //////////////////////////////////////////////////////////////////// // Initialize the property interpolator subsystem. Put into the INIT // group because the "nasal" subsystem may need it at GENERAL take-down. diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index 6a54db665..f18c5fb92 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -222,7 +222,7 @@ setFreeze (bool f) frozen = f; // Stop sound on a pause - SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); if ( smgr != NULL ) { if ( f ) { smgr->suspend(); diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 7e6553fa4..da3de6a46 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -15,8 +15,8 @@ // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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$ @@ -32,6 +32,7 @@ #include <simgear/scene/material/matlib.hxx> #include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/event_mgr.hxx> +#include <simgear/sound/soundmgr_openal.hxx> #include <Aircraft/controls.hxx> #include <Airports/runways.hxx> @@ -72,6 +73,7 @@ FGGlobals::FGGlobals() : renderer( new FGRenderer ), subsystem_mgr( new SGSubsystemMgr ), event_mgr( new SGEventMgr ), + soundmgr( new SGSoundMgr ), sim_time_sec( 0.0 ), fg_root( "" ), warp( 0 ), @@ -158,6 +160,9 @@ FGGlobals::~FGGlobals() delete channellist; delete airwaynet; delete multiplayer_mgr; + + soundmgr->unbind(); + delete soundmgr; } @@ -259,6 +264,11 @@ FGGlobals::add_subsystem (const char * name, subsystem_mgr->add(name, subsystem, type, min_time_sec); } +SGSoundMgr * +FGGlobals::get_soundmgr () const +{ + return soundmgr; +} SGEventMgr * FGGlobals::get_event_mgr () const diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index e778590dd..06490eaf3 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -52,6 +52,7 @@ class SGTime; class SGEventMgr; class SGSubsystemMgr; class SGSubsystem; +class SGSoundMgr; class FGAIMgr; class FGATCMgr; @@ -93,6 +94,7 @@ private: FGRenderer *renderer; SGSubsystemMgr *subsystem_mgr; SGEventMgr *event_mgr; + SGSoundMgr *soundmgr; // Number of milliseconds elapsed since the start of the program. double sim_time_sec; @@ -198,6 +200,8 @@ public: virtual SGEventMgr *get_event_mgr () const; + virtual SGSoundMgr *get_soundmgr () const; + inline double get_sim_time_sec () const { return sim_time_sec; } inline void inc_sim_time_sec (double dt) { sim_time_sec += dt; } inline void set_sim_time_sec (double t) { sim_time_sec = t; } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 30741f1c1..4ab21a885 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -482,7 +482,7 @@ static void fgMainLoop( void ) { // is processing the scenery (doubled the frame-rate for me) -EMH- //////////////////////////////////////////////////////////////////// #ifdef ENABLE_AUDIO_SUPPORT - static SGSoundMgr *smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + static SGSoundMgr *smgr = globals->get_soundmgr(); smgr->update_late(delta_time_sec); #endif @@ -636,13 +636,6 @@ static void fgIdleFunction ( void ) { } else if ( idle_state == 5 ) { idle_state++; -#ifdef ENABLE_AUDIO_SUPPORT - //////////////////////////////////////////////////////////////////// - // Add the Sound Manager before any other subsystem that uses it. - // This makes sure the SoundMgr is available at construction time. - //////////////////////////////////////////////////////////////////// - globals->add_subsystem("soundmgr", new SGSoundMgr); -#endif //////////////////////////////////////////////////////////////////// // Initialize the 3D aircraft model subsystem (has a dependency on diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index a23a28d79..6074dcf95 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -43,7 +43,7 @@ FGViewMgr::FGViewMgr( void ) : config_list(fgGetNode("/sim", true)->getChildren("view")), current(0) { - smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + smgr = globals->get_soundmgr(); } // Destructor diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 1dcf2bd22..65104a990 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -48,8 +48,7 @@ FGAircraftModel::FGAircraftModel () _speed_e(0), _speed_d(0) { - SGSoundMgr *smgr; - smgr = (SGSoundMgr *)globals->get_subsystem("soundmgr"); + SGSoundMgr *smgr = globals->get_soundmgr(); _fx = new FGFX(smgr, "fx"); _fx->init(); } diff --git a/src/Sound/beacon.cxx b/src/Sound/beacon.cxx index 497cbf032..4505017c9 100644 --- a/src/Sound/beacon.cxx +++ b/src/Sound/beacon.cxx @@ -21,7 +21,7 @@ // $Id$ -#include <memory> +#include <stdlib.h> #include "beacon.hxx" @@ -39,13 +39,12 @@ FGBeacon::~FGBeacon() { // allocate and initialize sound samples bool FGBeacon::init() { - int i; - int len; unsigned char *ptr; + size_t i, len; - std::auto_ptr<unsigned char>inner_buf( new unsigned char[ INNER_SIZE ] ); - std::auto_ptr<unsigned char>middle_buf( new unsigned char[ MIDDLE_SIZE ] ); - std::auto_ptr<unsigned char>outer_buf( new unsigned char[ OUTER_SIZE ] ); + const unsigned char* inner_buf = (const unsigned char*)malloc( INNER_SIZE ); + const unsigned char* middle_buf = (const unsigned char*)malloc(MIDDLE_SIZE); + const unsigned char* outer_buf = (const unsigned char*)malloc( OUTER_SIZE ); // Make inner marker beacon sound len= (int)(INNER_DIT_LEN / 2.0 ); @@ -53,14 +52,14 @@ bool FGBeacon::init() { make_tone( inner_dit, INNER_FREQ, len, INNER_DIT_LEN, TRANSITION_BYTES ); - ptr = inner_buf.get(); + ptr = (unsigned char*)inner_buf; for ( i = 0; i < 6; ++i ) { memcpy( ptr, inner_dit, INNER_DIT_LEN ); ptr += INNER_DIT_LEN; } try { - inner = new SGSoundSample( inner_buf, INNER_SIZE, BYTES_PER_SECOND ); + inner = new SGSoundSample( &inner_buf, INNER_SIZE, BYTES_PER_SECOND ); inner->set_reference_dist( 10.0 ); inner->set_max_dist( 20.0 ); @@ -75,12 +74,12 @@ bool FGBeacon::init() { make_tone( middle_dah, MIDDLE_FREQ, len, MIDDLE_DAH_LEN, TRANSITION_BYTES ); - ptr = middle_buf.get(); + ptr = (unsigned char*)middle_buf; memcpy( ptr, middle_dit, MIDDLE_DIT_LEN ); ptr += MIDDLE_DIT_LEN; memcpy( ptr, middle_dah, MIDDLE_DAH_LEN ); - middle = new SGSoundSample( middle_buf, MIDDLE_SIZE, BYTES_PER_SECOND ); + middle = new SGSoundSample( &middle_buf, MIDDLE_SIZE, BYTES_PER_SECOND); middle->set_reference_dist( 10.0 ); middle->set_max_dist( 20.0 ); @@ -90,12 +89,12 @@ bool FGBeacon::init() { make_tone( outer_dah, OUTER_FREQ, len, OUTER_DAH_LEN, TRANSITION_BYTES ); - ptr = outer_buf.get(); + ptr = (unsigned char*)outer_buf; memcpy( ptr, outer_dah, OUTER_DAH_LEN ); ptr += OUTER_DAH_LEN; memcpy( ptr, outer_dah, OUTER_DAH_LEN ); - outer = new SGSoundSample( outer_buf, OUTER_SIZE, BYTES_PER_SECOND ); + outer = new SGSoundSample( &outer_buf, OUTER_SIZE, BYTES_PER_SECOND ); outer->set_reference_dist( 10.0 ); outer->set_max_dist( 20.0 ); } catch ( sg_io_exception &e ) { diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx index 0943b8a86..942b637a5 100644 --- a/src/Sound/morse.cxx +++ b/src/Sound/morse.cxx @@ -21,8 +21,6 @@ // $Id$ -#include <memory> - #include <simgear/constants.h> #include "morse.hxx" @@ -221,10 +219,10 @@ SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) { length += 2 * SPACE_SIZE; // 2. Allocate space for the message - std::auto_ptr<unsigned char>buffer( new unsigned char[length] ); + const unsigned char* buffer = (const unsigned char *)malloc(length); // 3. Assemble the message; - unsigned char *buf_ptr = buffer.get(); + unsigned char *buf_ptr = (unsigned char*)buffer; for ( i = 0; i < (int)id.length(); ++i ) { if ( idptr[i] >= 'A' && idptr[i] <= 'Z' ) { @@ -263,7 +261,7 @@ SGSoundSample *FGMorse::make_ident( const string& id, const int freq ) { buf_ptr += SPACE_SIZE; // 4. create the simple sound and return - SGSoundSample *sample = new SGSoundSample( buffer, length, + SGSoundSample *sample = new SGSoundSample( &buffer, length, BYTES_PER_SECOND ); sample->set_reference_dist( 10.0 ); From 430fbe99fa7a1fbb3649ccdedb31beab87a5c040 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sat, 24 Oct 2009 12:57:50 +0000 Subject: [PATCH 20/62] Use shared pointers for any reference to SGSoundSample --- src/ATCDCL/AIPlane.cxx | 4 +--- src/ATCDCL/AIPlane.hxx | 2 +- src/ATCDCL/ATC.hxx | 3 ++- src/ATCDCL/ATCVoice.cxx | 27 +++++++++++++-------------- src/ATCDCL/ATCVoice.hxx | 5 +++-- src/Instrumentation/adf.hxx | 2 +- src/Instrumentation/kr_87.hxx | 2 +- src/Instrumentation/marker_beacon.hxx | 2 +- src/Instrumentation/mk_viii.cxx | 2 +- src/Instrumentation/mk_viii.hxx | 10 +++++----- src/Instrumentation/navradio.hxx | 2 +- src/Model/acmodel.hxx | 20 ++++++++++---------- src/Sound/sample_queue.hxx | 4 ++-- 13 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 3a46ee051..3f22dafa1 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -29,8 +29,6 @@ using std::string; #include "AIPlane.hxx" -SGSampleGroup *FGAIPlane::_sgr = 0; - FGAIPlane::FGAIPlane() { leg = LEG_UNKNOWN; tuned_station = NULL; @@ -198,7 +196,7 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating voice = (voiceOK && fgGetBool("/sim/sound/voice")); if(voice) { sizte_t len; - void* buf = vPtr->WriteMessage((char*)pending_transmission.c_str(), voice, &len); + void* buf = vPtr->WriteMessage(pending_transmission, &len); if(voice && (volume > 0.05)) { SGSoundSample* simple = new SGSoundSample(buf, len, 8000 ); simple->set_volume(volume); diff --git a/src/ATCDCL/AIPlane.hxx b/src/ATCDCL/AIPlane.hxx index e099cdfac..53158f929 100644 --- a/src/ATCDCL/AIPlane.hxx +++ b/src/ATCDCL/AIPlane.hxx @@ -160,7 +160,7 @@ private: double _tgtRoll; bool _rollSuspended; // Set true when a derived class has suspended AIPlane's roll control - static SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; }; #endif // _FG_AI_PLANE_HXX diff --git a/src/ATCDCL/ATC.hxx b/src/ATCDCL/ATC.hxx index 8b05d6ca0..dd3fc8be2 100644 --- a/src/ATCDCL/ATC.hxx +++ b/src/ATCDCL/ATC.hxx @@ -27,6 +27,7 @@ #include <simgear/misc/sgstream.hxx> #include <simgear/math/sg_geodesy.hxx> #include <simgear/debug/logstream.hxx> +#include <simgear/structure/SGSharedPtr.hxx> #include <iosfwd> #include <string> @@ -212,7 +213,7 @@ protected: bool _voiceOK; // Flag - true if at least one voice has loaded OK FGATCVoice* _vPtr; - SGSampleGroup *_sgr; // default sample group; + SGSharedPtr<SGSampleGroup> _sgr; // default sample group; bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx index 5659b1132..3648bfedd 100644 --- a/src/ATCDCL/ATCVoice.cxx +++ b/src/ATCDCL/ATCVoice.cxx @@ -72,10 +72,10 @@ bool FGATCVoice::LoadVoice(const string& voice) { string full_path = path.str(); int format, freq; - SGSoundMgr *smgr = globals->get_soundmgr(); + SGSoundMgr *smgr = globals->get_soundmgr(); void *data; - if (!smgr->load(full_path, &data, &format, &rawDataSize, &freq)) - return false; + if (!smgr->load(full_path, &data, &format, &rawDataSize, &freq)) + return false; rawSoundData = (char*)data; #ifdef VOICE_TEST cout << "ATCVoice: format: " << format @@ -118,7 +118,7 @@ bool FGATCVoice::LoadVoice(const string& voice) { *p = tolower(*p); if (*p == '-') *p = '_'; } - if (wrdstr != ws2) wordMap[ws2] = wd; + if (wrdstr != ws2) wordMap[ws2] = wd; //cout << wrd << "\t\t" << wrdOffset << "\t\t" << wrdLength << '\n'; //cout << i << '\n'; @@ -134,7 +134,7 @@ typedef tokenList_type::iterator tokenList_iterator; // Given a desired message, return a string containing the // sound-sample data -void* FGATCVoice::WriteMessage(const char* message, size_t* len) { +void* FGATCVoice::WriteMessage(const string& message, size_t* len) { // What should we do here? // First - parse the message into a list of tokens. @@ -145,14 +145,12 @@ void* FGATCVoice::WriteMessage(const char* message, size_t* len) { // TODO - at the moment we're effectively taking 3 passes through the data. // There is no need for this - 2 should be sufficient - we can probably ditch the tokenList. - size_t n1 = 1+strlen(message); - boost::shared_array<char> msg(new char[n1]); - strncpy(msg.get(), message, n1); // strtok requires a non-const char* + char* msg = (char *)message.c_str(); char* token; int numWords = 0; const char delimiters[] = " \t.,;:\"\n"; char* context; - token = strtok_r(msg.get(), delimiters, &context); + token = strtok_r(msg, delimiters, &context); while(token != NULL) { for (char *t = token; *t; t++) { *t = tolower(*t); // canonicalize the case, to @@ -173,7 +171,7 @@ void* FGATCVoice::WriteMessage(const char* message, size_t* len) { while(tokenListItr != tokenList.end()) { if(wordMap.find(*tokenListItr) == wordMap.end()) { // Oh dear - the token isn't in the sound file - SG_LOG(SG_ATC, SG_ALERT, "voice synth: word '" + SG_LOG(SG_ATC, SG_DEBUG, "voice synth: word '" << *tokenListItr << "' not found"); } else { wdptr.push_back(wordMap[*tokenListItr]); @@ -213,11 +211,12 @@ void* FGATCVoice::WriteMessage(const char* message, size_t* len) { unsigned int offsetIn = (int)(cumLength * sg_random()); if(offsetIn > cumLength) offsetIn = cumLength; - void *data = malloc(cumLength); - memcpy(data, tmpbuf.get(), cumLength); + unsigned char *data = (unsigned char *)calloc(1, cumLength); *len = cumLength; - // string front(tmpbuf.get(), offsetIn); - // string back(tmpbuf.get() + offsetIn, cumLength - offsetIn); +#if 0 +memcpy(data, tmpbuf.get() + offsetIn, cumLength - offsetIn); + memcpy(data + cumLength - offsetIn, tmpbuf.get(), offsetIn); +#endif return data; } diff --git a/src/ATCDCL/ATCVoice.hxx b/src/ATCDCL/ATCVoice.hxx index 6ec4f3932..5128cc55d 100644 --- a/src/ATCDCL/ATCVoice.hxx +++ b/src/ATCDCL/ATCVoice.hxx @@ -22,6 +22,7 @@ #define _FG_ATC_VOICE #include <simgear/compiler.h> +#include <simgear/structure/SGSharedPtr.hxx> #include <map> #include <string> @@ -50,14 +51,14 @@ public: // Given a desired message, return a pointer to the data buffer and write the buffer length into len. // Sets len to something other than 0 if the returned buffer is valid. - void* WriteMessage(const char* message, size_t *len); + void* WriteMessage(const std::string& message, size_t *len); private: // the sound and word position data char* rawSoundData; size_t rawDataSize; - SGSoundSample *SoundData; + SGSharedPtr<SGSoundSample> SoundData; // A map of words vs. byte position and length in rawSoundData atc_word_map_type wordMap; diff --git a/src/Instrumentation/adf.hxx b/src/Instrumentation/adf.hxx index 80de7d860..f2c2bdeb8 100644 --- a/src/Instrumentation/adf.hxx +++ b/src/Instrumentation/adf.hxx @@ -98,7 +98,7 @@ private: float _last_volume; string _adf_ident; - SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; }; diff --git a/src/Instrumentation/kr_87.hxx b/src/Instrumentation/kr_87.hxx index 0653b06d9..e59beba7b 100644 --- a/src/Instrumentation/kr_87.hxx +++ b/src/Instrumentation/kr_87.hxx @@ -105,7 +105,7 @@ class FGKR_87 : public SGSubsystem // internal periodic station search timer double _time_before_search_sec; - SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; public: diff --git a/src/Instrumentation/marker_beacon.hxx b/src/Instrumentation/marker_beacon.hxx index 774e37f81..3a98c11cd 100644 --- a/src/Instrumentation/marker_beacon.hxx +++ b/src/Instrumentation/marker_beacon.hxx @@ -74,7 +74,7 @@ class FGMarkerBeacon : public SGSubsystem // internal periodic station search timer double _time_before_search_sec; - SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; public: diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index f2a4dba2c..a3073136a 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2111,7 +2111,7 @@ MK_VIII::VoicePlayer::Speaker::bind (SGPropertyNode *node) void MK_VIII::VoicePlayer::Speaker::update_configuration () { - map<string, SGSoundSample *>::iterator iter; + map< string, SGSharedPtr<SGSoundSample> >::iterator iter; for (iter = player->samples.begin(); iter != player->samples.end(); iter++) { SGSoundSample *sample = (*iter).second; diff --git a/src/Instrumentation/mk_viii.hxx b/src/Instrumentation/mk_viii.hxx index 077ea52ab..3e48ea2b4 100755 --- a/src/Instrumentation/mk_viii.hxx +++ b/src/Instrumentation/mk_viii.hxx @@ -747,11 +747,11 @@ public: class SampleElement : public Element { - SGSoundSample *_sample; - float _volume; + SGSharedPtr<SGSoundSample> _sample; + float _volume; public: - inline SampleElement (SGSoundSample *sample, float volume = 1.0) + inline SampleElement (SGSharedPtr<SGSoundSample> sample, float volume = 1.0) : _sample(sample), _volume(volume) { silence = false; } virtual inline void play (float volume) { if (_sample && (volume > 0.05)) { set_volume(volume); _sample->play_once(); } } @@ -928,10 +928,10 @@ public: MK_VIII *mk; - SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; Speaker speaker; - map<string, SGSoundSample *> samples; + map< string, SGSharedPtr<SGSoundSample> > samples; vector<Voice *> _voices; bool looped; diff --git a/src/Instrumentation/navradio.hxx b/src/Instrumentation/navradio.hxx index 978e77d6f..6dbe3b78e 100644 --- a/src/Instrumentation/navradio.hxx +++ b/src/Instrumentation/navradio.hxx @@ -160,7 +160,7 @@ class FGNavRadio : public SGSubsystem // realism setting, are false courses and GS lobes enabled? bool _falseCoursesEnabled; - SGSampleGroup *_sgr; + SGSharedPtr<SGSampleGroup> _sgr; bool updateWithPower(double aDt); diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index c751b699c..f9917a1d7 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -45,17 +45,17 @@ private: SGModelPlacement * _aircraft; SGVec3d _velocity; - FGFX * _fx; + SGSharedPtr<FGFX> _fx; - SGPropertyNode * _lon; - SGPropertyNode * _lat; - SGPropertyNode * _alt; - SGPropertyNode * _pitch; - SGPropertyNode * _roll; - SGPropertyNode * _heading; - SGPropertyNode * _speed_n; - SGPropertyNode * _speed_e; - SGPropertyNode * _speed_d; + SGPropertyNode_ptr _lon; + SGPropertyNode_ptr _lat; + SGPropertyNode_ptr _alt; + SGPropertyNode_ptr _pitch; + SGPropertyNode_ptr _roll; + SGPropertyNode_ptr _heading; + SGPropertyNode_ptr _speed_n; + SGPropertyNode_ptr _speed_e; + SGPropertyNode_ptr _speed_d; }; #endif // __ACMODEL_HXX diff --git a/src/Sound/sample_queue.hxx b/src/Sound/sample_queue.hxx index c874ae3eb..88b30ae75 100644 --- a/src/Sound/sample_queue.hxx +++ b/src/Sound/sample_queue.hxx @@ -51,11 +51,11 @@ public: virtual void update (double dt); - inline void add (SGSoundSample *msg) { _messages.push(msg); } + inline void add (SGSharedPtr<SGSoundSample> msg) { _messages.push(msg); } private: - std::queue<SGSoundSample *> _messages; + std::queue< SGSharedPtr<SGSoundSample> > _messages; bool last_pause; double last_volume; From fc71333bdd0217a9ff4880305daf6d4d10fb0b40 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore@redhat.com> Date: Sat, 24 Oct 2009 23:14:48 +0200 Subject: [PATCH 21/62] Fix typo --- src/ATCDCL/AIPlane.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 3f22dafa1..9ab162b6f 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -195,7 +195,7 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating #ifdef ENABLE_AUDIO_SUPPORT voice = (voiceOK && fgGetBool("/sim/sound/voice")); if(voice) { - sizte_t len; + size_t len; void* buf = vPtr->WriteMessage(pending_transmission, &len); if(voice && (volume > 0.05)) { SGSoundSample* simple = new SGSoundSample(buf, len, 8000 ); From 11d15b451347674fba77648700d23c5aaec3c6c2 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 26 Oct 2009 09:47:16 +0000 Subject: [PATCH 22/62] fix a pointer reference. --- src/ATCDCL/AIPlane.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ATCDCL/AIPlane.cxx b/src/ATCDCL/AIPlane.cxx index 9ab162b6f..8fd67d13a 100644 --- a/src/ATCDCL/AIPlane.cxx +++ b/src/ATCDCL/AIPlane.cxx @@ -198,7 +198,7 @@ void FGAIPlane::Render(const string& refname, const float volume, bool repeating size_t len; void* buf = vPtr->WriteMessage(pending_transmission, &len); if(voice && (volume > 0.05)) { - SGSoundSample* simple = new SGSoundSample(buf, len, 8000 ); + SGSoundSample* simple = new SGSoundSample(&buf, len, 8000 ); simple->set_volume(volume); _sgr->add(simple, refname); _sgr->play(refname, repeating); From ad020f5fb549baf41574c54871471ead2d685693 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 26 Oct 2009 13:31:41 +0000 Subject: [PATCH 23/62] Csaba Halasz: C++-ify ATCVoice WriteMessage --- src/ATCDCL/ATCVoice.cxx | 138 +++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 79 deletions(-) diff --git a/src/ATCDCL/ATCVoice.cxx b/src/ATCDCL/ATCVoice.cxx index 3648bfedd..7437884f7 100644 --- a/src/ATCDCL/ATCVoice.cxx +++ b/src/ATCDCL/ATCVoice.cxx @@ -28,10 +28,8 @@ #include <stdlib.h> #include <ctype.h> #include <fstream> -#include <list> #include <vector> - -#include <boost/shared_array.hpp> +#include <algorithm> #include <simgear/sound/soundmgr_openal.hxx> #include <simgear/misc/sg_path.hxx> @@ -41,12 +39,6 @@ #include <Main/globals.hxx> -#include <stdio.h> - -#ifdef _MSC_VER -#define strtok_r strtok_s -#endif - using namespace std; FGATCVoice::FGATCVoice() { @@ -129,9 +121,6 @@ bool FGATCVoice::LoadVoice(const string& voice) { } -typedef list < string > tokenList_type; -typedef tokenList_type::iterator tokenList_iterator; - // Given a desired message, return a string containing the // sound-sample data void* FGATCVoice::WriteMessage(const string& message, size_t* len) { @@ -140,83 +129,74 @@ void* FGATCVoice::WriteMessage(const string& message, size_t* len) { // First - parse the message into a list of tokens. // Sort the tokens into those we understand and those we don't. // Add all the raw lengths of the token sound data, allocate enough space, and fill it with the rqd data. - tokenList_type tokenList; - tokenList_iterator tokenListItr; - // TODO - at the moment we're effectively taking 3 passes through the data. - // There is no need for this - 2 should be sufficient - we can probably ditch the tokenList. - char* msg = (char *)message.c_str(); - char* token; - int numWords = 0; + vector<char> sound; const char delimiters[] = " \t.,;:\"\n"; - char* context; - token = strtok_r(msg, delimiters, &context); - while(token != NULL) { - for (char *t = token; *t; t++) { - *t = tolower(*t); // canonicalize the case, to - if (*t == '-') *t = '_'; // match what's in the index - } - tokenList.push_back(token); - ++numWords; - SG_LOG(SG_ATC, SG_DEBUG, "voice synth: token: '" - << token << "'"); - token = strtok_r(NULL, delimiters, &context); - } - - vector<WordData> wdptr; - wdptr.reserve(numWords); - unsigned int cumLength = 0; - - tokenListItr = tokenList.begin(); - while(tokenListItr != tokenList.end()) { - if(wordMap.find(*tokenListItr) == wordMap.end()) { - // Oh dear - the token isn't in the sound file - SG_LOG(SG_ATC, SG_DEBUG, "voice synth: word '" - << *tokenListItr << "' not found"); + string::size_type token_start = message.find_first_not_of(delimiters); + while(token_start != string::npos) { + string::size_type token_end = message.find_first_of(delimiters, token_start); + string token; + if (token_end == string::npos) { + token = message.substr(token_start); + token_start = string::npos; } else { - wdptr.push_back(wordMap[*tokenListItr]); - cumLength += wdptr.back().length; + token = message.substr(token_start, token_end - token_start); + token_start = message.find_first_not_of(delimiters, token_end); + } + + for(string::iterator t = token.begin(); t != token.end(); t++) { + // canonicalize the token, to match what's in the index + *t = (*t == '-') ? '_' : tolower(*t); + } + SG_LOG(SG_ATC, SG_DEBUG, "voice synth: token: '" + << token << "'"); + + atc_word_map_const_iterator wordIt = wordMap.find(token); + if(wordIt == wordMap.end()) { + // Oh dear - the token isn't in the sound file + SG_LOG(SG_ATC, SG_ALERT, "voice synth: word '" + << token << "' not found"); + } else { + const WordData& word = wordIt->second; + /* + * Sanity check for corrupt/mismatched sound data input - avoids a seg fault + * (As long as the calling function checks the return value!!) + * This check should be left in even when the default Flightgear files are known + * to be OK since it checks for mis-indexing of voice files by 3rd party developers. + */ + if((word.offset + word.length) > rawDataSize) { + SG_LOG(SG_ATC, SG_ALERT, "ERROR - mismatch between ATC .wav and .vce file in ATCVoice.cxx\n"); + SG_LOG(SG_ATC, SG_ALERT, "Offset + length: " << word.offset + word.length + << " exceeds rawdata size: " << rawDataSize << endl); + + *len = 0; + return 0; + } + sound.insert(sound.end(), rawSoundData + word.offset, rawSoundData + word.offset + word.length); } - ++tokenListItr; } - const size_t word = wdptr.size(); - + // Check for no tokens found else slScheduler can be crashed - if(!word) { + *len = sound.size(); + if (*len == 0) { + return 0; + } + + char* data = (char*)malloc(*len); + if (data == 0) { + SG_LOG(SG_ATC, SG_ALERT, "ERROR - could not allocate " << *len << " bytes of memory for ATIS sound\n"); *len = 0; - return NULL; + return 0; } - boost::shared_array<char> tmpbuf(new char[cumLength]); - unsigned int bufpos = 0; - for(int i=0; i<word; ++i) { - /* - * Sanity check for corrupt/mismatched sound data input - avoids a seg fault - * (As long as the calling function checks the return value!!) - * This check should be left in even when the default Flightgear files are known - * to be OK since it checks for mis-indexing of voice files by 3rd party developers. - */ - if((wdptr[i].offset + wdptr[i].length) > rawDataSize) { - SG_LOG(SG_ATC, SG_ALERT, "ERROR - mismatch between ATC .wav and .vce file in ATCVoice.cxx\n"); - SG_LOG(SG_ATC, SG_ALERT, "Offset + length: " << wdptr[i].offset + wdptr[i].length - << " exceeds rawdata size: " << rawDataSize << endl); - *len = 0; - return NULL; - } - memcpy(tmpbuf.get() + bufpos, rawSoundData + wdptr[i].offset, wdptr[i].length); - bufpos += wdptr[i].length; + // randomize start position + unsigned int offsetIn = (unsigned int)(*len * sg_random()); + if (offsetIn > 0 && offsetIn < *len) { + copy(sound.begin() + offsetIn, sound.end(), data); + copy(sound.begin(), sound.begin() + offsetIn, data + *len - offsetIn); + } else { + copy(sound.begin(), sound.end(), data); } - - // tmpbuf now contains the message starting at the beginning - but we want it to start at a random position. - unsigned int offsetIn = (int)(cumLength * sg_random()); - if(offsetIn > cumLength) offsetIn = cumLength; - - unsigned char *data = (unsigned char *)calloc(1, cumLength); - *len = cumLength; -#if 0 -memcpy(data, tmpbuf.get() + offsetIn, cumLength - offsetIn); - memcpy(data + cumLength - offsetIn, tmpbuf.get(), offsetIn); -#endif return data; } From c56c520ab5baa9e5cb1c651bc0ac887aab1637f0 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 28 Oct 2009 14:29:38 +0000 Subject: [PATCH 24/62] initlialize _playing for FGATC. Proper listerner orientation based on view offset. proper velocity orientation --- src/ATCDCL/ATC.cxx | 1 + src/Main/main.cxx | 14 ++++++-------- src/Main/viewer.cxx | 8 ++++---- src/Main/viewer.hxx | 2 ++ src/Main/viewmgr.cxx | 3 ++- src/Model/acmodel.cxx | 7 ++++--- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 7e17f1da7..b4a17ae97 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -36,6 +36,7 @@ FGATC::FGATC() : _voiceOK(false), + _playing(false), _sgr(NULL), freqClear(true), receiving(false), diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 4ab21a885..66bf3c6d8 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -460,8 +460,8 @@ static void fgMainLoop( void ) { // we may want to move this to its own class at some point // double visibility_meters = fgGetDouble("/environment/visibility-m"); - globals->get_tile_mgr()->prep_ssg_nodes( visibility_meters ); + // update tile manager for view... SGVec3d viewPos = globals->get_current_view()->get_view_pos(); SGGeod geodViewPos = SGGeod::fromCart(viewPos); @@ -477,13 +477,10 @@ static void fgMainLoop( void ) { // update the view angle as late as possible, but before sound calculations globals->get_viewmgr()->update(real_delta_time_sec); - //////////////////////////////////////////////////////////////////// // Update the sound manager last so it can use the CPU while the GPU // is processing the scenery (doubled the frame-rate for me) -EMH- - //////////////////////////////////////////////////////////////////// #ifdef ENABLE_AUDIO_SUPPORT - static SGSoundMgr *smgr = globals->get_soundmgr(); - smgr->update_late(delta_time_sec); + globals->get_soundmgr()->update(delta_time_sec); #endif // END Tile Manager udpates @@ -493,11 +490,12 @@ static void fgMainLoop( void ) { fgSetBool("sim/sceneryloaded",true); #ifdef ENABLE_AUDIO_SUPPORT if (fgGetBool("/sim/sound/enabled") == true) { - smgr->set_volume(fgGetFloat("/sim/sound/volume")); - smgr->activate(); + float volume = fgGetFloat("/sim/sound/volume"); + globals->get_soundmgr()->set_volume(volume); + globals->get_soundmgr()->activate(); } else - smgr->stop(); + globals->get_soundmgr()->stop(); #endif } diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index 2e34db687..8dcfb982d 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -380,7 +380,7 @@ FGViewer::recalcLookFrom () SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll); // The rotation offset, don't know why heading is negative here ... - SGQuatd viewOffsetOr + mViewOffsetOr = SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg, _roll_offset_deg); @@ -396,7 +396,7 @@ FGViewer::recalcLookFrom () SGQuatd q(-0.5, -0.5, 0.5, 0.5); _absolute_view_pos = position + (ec2body*q).backTransform(_offset_m); - mViewOrientation = ec2body*viewOffsetOr*q; + mViewOrientation = ec2body*mViewOffsetOr*q; } void @@ -437,7 +437,7 @@ FGViewer::recalcLookAt () SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(_position); // the rotation offset, don't know why heading is negative here ... - SGQuatd eyeOffsetOr = + mViewOffsetOr = SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg, _roll_offset_deg); @@ -445,7 +445,7 @@ FGViewer::recalcLookAt () SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y()); SGQuatd ec2eye = geodEyeHlOr*geodEyeOr; SGVec3d eyeCart = SGVec3d::fromGeod(_position); - eyeCart += (ec2eye*eyeOffsetOr).backTransform(eyeOff); + eyeCart += (ec2eye*mViewOffsetOr).backTransform(eyeOff); SGVec3d atCart = SGVec3d::fromGeod(_target); diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index 965e8569a..aa5fb1212 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -201,6 +201,7 @@ public: const SGVec3d& get_view_pos() { if ( _dirty ) { recalc(); } return _absolute_view_pos; } const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; } const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; } + const SGQuatd& getViewOrientationOffset() { if ( _dirty ) { recalc(); } return mViewOffsetOr; } ////////////////////////////////////////////////////////////////////// // Part 4: View and frustrum data setters and getters @@ -247,6 +248,7 @@ private: bool _dirty; SGQuatd mViewOrientation; + SGQuatd mViewOffsetOr; SGVec3d _absolute_view_pos; SGGeod _position; diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 6074dcf95..cc254991b 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -299,7 +299,8 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters smgr->set_position( abs_viewer_position ); - smgr->set_orientation(loop_view->getViewOrientation()); + smgr->set_orientation(loop_view->getViewOrientation(), + loop_view->getViewOrientationOffset()); // get the model velocity for the in-cockpit view SGVec3d velocity = SGVec3d(0,0,0); diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 65104a990..1a93a49ab 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -131,9 +131,10 @@ FGAircraftModel::update (double dt) _roll->getDoubleValue()); _fx->set_orientation( orient ); - _velocity = SGVec3d( -_speed_n->getDoubleValue(), - _speed_e->getDoubleValue(), - _speed_d->getDoubleValue()); + SGQuatd q(-0.5, -0.5, 0.5, 0.5); + _velocity = q.backTransform( SGVec3d( _speed_n->getDoubleValue(), + _speed_e->getDoubleValue(), + _speed_d->getDoubleValue()) ); _fx->set_velocity( _velocity ); } From 9535c4e339eeab8e9f255ef134dc50ec4cabee30 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 29 Oct 2009 13:34:43 +0000 Subject: [PATCH 25/62] Commit the current state of affairs to see if it fixes the position code for others --- src/Main/viewmgr.cxx | 7 +++---- src/Model/acmodel.cxx | 8 ++++---- src/Model/acmodel.hxx | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index cc254991b..b31b9912b 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -302,11 +302,10 @@ FGViewMgr::update (double dt) smgr->set_orientation(loop_view->getViewOrientation(), loop_view->getViewOrientationOffset()); - // get the model velocity for the in-cockpit view - SGVec3d velocity = SGVec3d(0,0,0); + // get the model velocity + SGVec3f velocity = SGVec3f::zeros(); if ( !stationary() ) { - FGAircraftModel *aircraft = globals->get_aircraft_model(); - velocity = aircraft->getVelocity(); + velocity = globals->get_aircraft_model()->getVelocity(); } smgr->set_velocity(velocity); } diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 1a93a49ab..305c1fbeb 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -131,10 +131,10 @@ FGAircraftModel::update (double dt) _roll->getDoubleValue()); _fx->set_orientation( orient ); - SGQuatd q(-0.5, -0.5, 0.5, 0.5); - _velocity = q.backTransform( SGVec3d( _speed_n->getDoubleValue(), - _speed_e->getDoubleValue(), - _speed_d->getDoubleValue()) ); + SGQuatf q(-0.5, -0.5, 0.5, 0.5); + _velocity = q.backTransform( SGVec3f(_speed_n->getFloatValue(), + _speed_e->getFloatValue(), + _speed_d->getFloatValue()) ); _fx->set_velocity( _velocity ); } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index f9917a1d7..da3c844f5 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -39,12 +39,12 @@ public: virtual void unbind (); virtual void update (double dt); virtual SGModelPlacement * get3DModel() { return _aircraft; } - virtual SGVec3d getVelocity() { return _velocity; } + virtual SGVec3f& getVelocity() { return _velocity; } private: SGModelPlacement * _aircraft; - SGVec3d _velocity; + SGVec3f _velocity; SGSharedPtr<FGFX> _fx; SGPropertyNode_ptr _lon; From d2799cd8321e964ecc87e5deb9a4c61c3c12e69c Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sat, 31 Oct 2009 14:20:14 +0000 Subject: [PATCH 26/62] another attempt at getting something useful without any result. --- src/Main/viewmgr.cxx | 13 ++++++++++--- src/Model/acmodel.cxx | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index b31b9912b..5a9b7a20f 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -298,9 +298,16 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position( abs_viewer_position ); - smgr->set_orientation(loop_view->getViewOrientation(), - loop_view->getViewOrientationOffset()); + SGVec3d offs = SGVec3d( loop_view->getXOffset_m(), + loop_view->getYOffset_m(), + loop_view->getZOffset_m()); + smgr->set_position_offset( offs ); + smgr->set_position_geod( loop_view->getPosition() ); + + SGQuatd orient = SGQuatd::fromYawPitchRollDeg( loop_view->getHeading_deg(), + loop_view->getPitch_deg(), + loop_view->getRoll_deg() ); + smgr->set_orientation( orient, loop_view->getViewOrientationOffset() ); // get the model velocity SGVec3f velocity = SGVec3f::zeros(); diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 305c1fbeb..6d0d32049 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -124,17 +124,23 @@ FGAircraftModel::update (double dt) _aircraft->update(); // update model's audio sample values - _fx->set_position( _aircraft->getPosition() ); + _fx->set_position_geod( _aircraft->getPosition() ); - SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), + SGQuatd orient = SGQuatd::fromYawPitchRollDeg(-_heading->getDoubleValue(), _pitch->getDoubleValue(), _roll->getDoubleValue()); _fx->set_orientation( orient ); - SGQuatf q(-0.5, -0.5, 0.5, 0.5); - _velocity = q.backTransform( SGVec3f(_speed_n->getFloatValue(), - _speed_e->getFloatValue(), - _speed_d->getFloatValue()) ); + SGVec3d vel = SGVec3d( _speed_n->getFloatValue(), + _speed_e->getFloatValue(), + _speed_d->getFloatValue() ); + if ( vel[0] || vel[1] || vel[2] ) { + SGQuatd hlOr = SGQuatd::fromLonLat( _aircraft->getPosition() ); + SGQuatd q(-0.5, -0.5, 0.5, 0.5); + _velocity = toVec3f( (hlOr*q).backTransform( vel ) ); + } + else + _velocity = SGVec3f::zeros(); _fx->set_velocity( _velocity ); } From 7efed5347542eb6cdf713da7f2bf68dec7464089 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 1 Nov 2009 14:53:36 +0000 Subject: [PATCH 27/62] proper sound orientation(?) and comment out velocity since it messes with OpenAL in such a way that volume doesn't work properly anymore --- src/Main/viewmgr.cxx | 6 ++---- src/Model/acmodel.cxx | 7 ++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 5a9b7a20f..60cfdb437 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -304,10 +304,8 @@ FGViewMgr::update (double dt) smgr->set_position_offset( offs ); smgr->set_position_geod( loop_view->getPosition() ); - SGQuatd orient = SGQuatd::fromYawPitchRollDeg( loop_view->getHeading_deg(), - loop_view->getPitch_deg(), - loop_view->getRoll_deg() ); - smgr->set_orientation( orient, loop_view->getViewOrientationOffset() ); + smgr->set_orientation( loop_view->getViewOrientation(), + loop_view->getViewOrientationOffset() ); // get the model velocity SGVec3f velocity = SGVec3f::zeros(); diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 6d0d32049..3b5ccfb13 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -126,21 +126,22 @@ FGAircraftModel::update (double dt) // update model's audio sample values _fx->set_position_geod( _aircraft->getPosition() ); - SGQuatd orient = SGQuatd::fromYawPitchRollDeg(-_heading->getDoubleValue(), + SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), _pitch->getDoubleValue(), _roll->getDoubleValue()); _fx->set_orientation( orient ); +#if 0 SGVec3d vel = SGVec3d( _speed_n->getFloatValue(), _speed_e->getFloatValue(), _speed_d->getFloatValue() ); if ( vel[0] || vel[1] || vel[2] ) { - SGQuatd hlOr = SGQuatd::fromLonLat( _aircraft->getPosition() ); SGQuatd q(-0.5, -0.5, 0.5, 0.5); - _velocity = toVec3f( (hlOr*q).backTransform( vel ) ); + _velocity = toVec3f( q.backTransform( vel ) ); } else _velocity = SGVec3f::zeros(); +#endif _fx->set_velocity( _velocity ); } From 6e5673de21e199f8a26bdd50b231177adeb96ca5 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 2 Nov 2009 10:31:42 +0000 Subject: [PATCH 28/62] Position and orientation fixes for the sound code, thanks to Tim Moore --- src/Main/viewmgr.cxx | 8 +------- src/Model/acmodel.cxx | 9 ++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 60cfdb437..6dbc5f2ad 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -298,14 +298,8 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - SGVec3d offs = SGVec3d( loop_view->getXOffset_m(), - loop_view->getYOffset_m(), - loop_view->getZOffset_m()); - smgr->set_position_offset( offs ); smgr->set_position_geod( loop_view->getPosition() ); - - smgr->set_orientation( loop_view->getViewOrientation(), - loop_view->getViewOrientationOffset() ); + smgr->set_orientation( loop_view->getViewOrientation() ); // get the model velocity SGVec3f velocity = SGVec3f::zeros(); diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 3b5ccfb13..187e27042 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -124,24 +124,23 @@ FGAircraftModel::update (double dt) _aircraft->update(); // update model's audio sample values - _fx->set_position_geod( _aircraft->getPosition() ); + SGGeod position = _aircraft->getPosition(); + _fx->set_position_geod( position ); SGQuatd orient = SGQuatd::fromYawPitchRollDeg(_heading->getDoubleValue(), _pitch->getDoubleValue(), _roll->getDoubleValue()); _fx->set_orientation( orient ); -#if 0 SGVec3d vel = SGVec3d( _speed_n->getFloatValue(), _speed_e->getFloatValue(), _speed_d->getFloatValue() ); if ( vel[0] || vel[1] || vel[2] ) { - SGQuatd q(-0.5, -0.5, 0.5, 0.5); - _velocity = toVec3f( q.backTransform( vel ) ); + SGQuatd hlOr = SGQuatd::fromLonLat(position); + _velocity = toVec3f( hlOr.backTransform( vel * SG_FEET_TO_METER ) ); } else _velocity = SGVec3f::zeros(); -#endif _fx->set_velocity( _velocity ); } From 0be434936ea3be0f9f5427e56daf52a95576e9d8 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 2 Nov 2009 13:26:45 +0000 Subject: [PATCH 29/62] John Denker: Simplify redundant code and superfluous variable --- src/Main/viewmgr.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 6dbc5f2ad..d73ef8744 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -241,11 +241,10 @@ FGViewMgr::unbind () void FGViewMgr::update (double dt) { - FGViewer * view = get_current_view(); - if (view == 0) - return; FGViewer *loop_view = (FGViewer *)get_view(current); + if (loop_view == 0) return; + SGPropertyNode *n = config_list[current]; double lon_deg, lat_deg, alt_ft, roll_deg, pitch_deg, heading_deg; @@ -293,7 +292,7 @@ FGViewMgr::update (double dt) // Update the current view do_axes(); - view->update(dt); + loop_view->update(dt); abs_viewer_position = loop_view->getViewPosition(); // update audio listener values From 3b5792e7cc6ca9729896f7d58c941014859d6d20 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 2 Nov 2009 13:48:09 +0000 Subject: [PATCH 30/62] minor upodate by John --- src/Main/viewmgr.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index d73ef8744..36ddc60f5 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -242,7 +242,7 @@ void FGViewMgr::update (double dt) { - FGViewer *loop_view = (FGViewer *)get_view(current); + FGViewer *loop_view = (FGViewer *)get_current_view(); if (loop_view == 0) return; SGPropertyNode *n = config_list[current]; From 342744fddb16911c807632797371bbc3d328b72e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 3 Nov 2009 09:59:05 +0000 Subject: [PATCH 31/62] Use the proper absolute position for the listener --- src/Main/viewmgr.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 36ddc60f5..544076b98 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -297,7 +297,7 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position_geod( loop_view->getPosition() ); + smgr->set_position( abs_viewer_position ); smgr->set_orientation( loop_view->getViewOrientation() ); // get the model velocity From c8430ce1040db155b231c45b6a6174203b3d7956 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 3 Nov 2009 12:58:35 +0000 Subject: [PATCH 32/62] I really have no idea why but the velocity should be 100 times larger than feet-per-second suggests to work properly. oh and change sign --- src/Model/acmodel.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 187e27042..4df8f19f1 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -137,7 +137,7 @@ FGAircraftModel::update (double dt) _speed_d->getFloatValue() ); if ( vel[0] || vel[1] || vel[2] ) { SGQuatd hlOr = SGQuatd::fromLonLat(position); - _velocity = toVec3f( hlOr.backTransform( vel * SG_FEET_TO_METER ) ); + _velocity = 100.0 * toVec3f( hlOr.rotateBack( vel * SG_FEET_TO_METER ) ); } else _velocity = SGVec3f::zeros(); From ab149d0036f21fd2ad685f7efea28f84986534b0 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 5 Nov 2009 09:18:27 +0000 Subject: [PATCH 33/62] John Denker: Add a view debugging functions and represent the viewer quats in the property tree for debugging. Do a nontrivial calculation, demonstrating how to find the 12:00 orientation given the view and the view offset. it, and observe that the 12:00 direction does not change when you change the view offset, which is a nontrivial result. Erik: This already proved to be useful since I now obserbed that the sky and fog coloring code depends on view offset rather that the view orientations. This is why those effects are out of line in some views. --- src/Main/viewmgr.cxx | 73 +++++++++++++++++++++++++++++++++++++++++++- src/Main/viewmgr.hxx | 9 ++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 544076b98..5f8485a68 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -28,6 +28,7 @@ #include "viewmgr.hxx" #include <string.h> // strcmp +#include <boost/format.hpp> #include <simgear/compiler.h> #include <simgear/sound/soundmgr_openal.hxx> @@ -162,6 +163,9 @@ typedef double (FGViewMgr::*double_getter)() const; void FGViewMgr::bind () { +// for automatic untying: +#define x(str) ((void)tied_props.push_back(str), str) + // these are bound to the current view properties fgTie("/sim/current-view/heading-offset-deg", this, &FGViewMgr::getViewHeadingOffset_deg, @@ -212,10 +216,20 @@ FGViewMgr::bind () &FGViewMgr::getNear_m, &FGViewMgr::setNear_m); fgSetArchivable("/sim/current-view/ground-level-nearplane-m"); + fgTie(x("/sim/current-view/view_orientation"), this, + &FGViewMgr::getCurrentViewOrientation); + fgTie(x("/sim/current-view/view_or_offset"), this, + &FGViewMgr::getCurrentViewOrOffset); + + fgTie(x("/sim/current-view/view1200"), this, + &FGViewMgr::getCurrentView1200); + SGPropertyNode *n = fgGetNode("/sim/current-view", true); n->tie("viewer-x-m", SGRawValuePointer<double>(&abs_viewer_position[0])); n->tie("viewer-y-m", SGRawValuePointer<double>(&abs_viewer_position[1])); n->tie("viewer-z-m", SGRawValuePointer<double>(&abs_viewer_position[2])); + +#undef x } void @@ -236,6 +250,12 @@ FGViewMgr::unbind () fgUntie("/sim/current-view/viewer-x-m"); fgUntie("/sim/current-view/viewer-y-m"); fgUntie("/sim/current-view/viewer-z-m"); + + list<const char*>::const_iterator it; + for (it = tied_props.begin(); it != tied_props.end(); it++){ + fgUntie(*it); + } + } void @@ -290,6 +310,9 @@ FGViewMgr::update (double dt) setViewTargetYOffset_m(fgGetDouble("/sim/current-view/target-y-offset-m")); setViewTargetZOffset_m(fgGetDouble("/sim/current-view/target-z-offset-m")); + current_view_orientation = loop_view->getViewOrientation(); + current_view_or_offset = loop_view->getViewOrientationOffset(); + // Update the current view do_axes(); loop_view->update(dt); @@ -298,7 +321,7 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters smgr->set_position( abs_viewer_position ); - smgr->set_orientation( loop_view->getViewOrientation() ); + smgr->set_orientation( current_view_orientation ); // get the model velocity SGVec3f velocity = SGVec3f::zeros(); @@ -747,6 +770,54 @@ FGViewMgr::setViewAxisLat (double axis) axis_lat = axis; } +static const char* fmt("%6.3f ; %6.3f %6.3f %6.3f"); + +// current view orientation +// This is a rotation relative to the earth-centered (ec) +// refrence frame. +// However, the components of this quaternion are expressed +// in the OpenGL camera system i.e. x-right, y-up, z-back. +const char* FGViewMgr::getCurrentViewOrientation() const{ + return str(boost::format(fmt) + % current_view_orientation.w() + % current_view_orientation.x() + % current_view_orientation.y() + % current_view_orientation.z() ).c_str(); +} + +// This rotation takes you from the 12:00 direction +// i.e. body attitude +// to whatever the current view direction is. +// The components of this quaternion are expressed in +// the XYZ body frame. +const char* FGViewMgr::getCurrentViewOrOffset() const{ + return str(boost::format(fmt) + % current_view_or_offset.w() + % current_view_or_offset.x() + % current_view_or_offset.y() + % current_view_or_offset.z() ).c_str(); +} + +// This rotates the conventional aviation XYZ body system +// i.e. x-forward, y-starboard, z-bottom +// to the OpenGL camera system +// i.e. x-right, y-up, z-back. +const SGQuatd q(-0.5, -0.5, 0.5, 0.5); + +// The current attitude of the aircraft, +// i.e. the 12:00 direction. +// The components of this quaternion are expressed in +// the GL camera frame. +const char* FGViewMgr::getCurrentView1200() const{ + SGQuatd view1200 = current_view_orientation + * conj(q) * conj(current_view_or_offset) * q; + return str(boost::format(fmt) + % view1200.w() + % view1200.x() + % view1200.y() + % view1200.z() ).c_str(); +} + void FGViewMgr::do_axes () { diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 2c0feb428..f1a0eccd4 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -25,6 +25,7 @@ #define _VIEWMGR_HXX #include <vector> +#include <list> #include <simgear/compiler.h> #include <simgear/structure/subsystem_mgr.hxx> @@ -76,6 +77,8 @@ public: private: + list<const char*> tied_props; + double axis_long; double axis_lat; @@ -116,6 +119,11 @@ private: void setViewAxisLat (double axis); int getView () const; void setView (int newview); +// quaternion accessors: + const char* getCurrentViewOrientation() const; + const char* getCurrentViewOrOffset() const; + const char* getCurrentView1200() const; + bool stationary () const; SGPropertyNode_ptr view_number; @@ -125,6 +133,7 @@ private: SGVec3d abs_viewer_position; int current; + SGQuatd current_view_orientation, current_view_or_offset; SGSoundMgr *smgr; From b8f50137510f778e6f9ebdae7520efcf14262404 Mon Sep 17 00:00:00 2001 From: Csaba Halasz <hcs@vostro.(none)> Date: Sun, 25 Oct 2009 16:08:38 +0100 Subject: [PATCH 34/62] Added some null pointer checks in FGAILocalTraffic to handle airports without tower --- src/ATCDCL/AILocalTraffic.cxx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ATCDCL/AILocalTraffic.cxx b/src/ATCDCL/AILocalTraffic.cxx index 2acf7d10d..6c1b77d8f 100644 --- a/src/ATCDCL/AILocalTraffic.cxx +++ b/src/ATCDCL/AILocalTraffic.cxx @@ -841,7 +841,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { // TODO - At hot 'n high airports this may be 500ft AGL though - need to make this a variable. if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 700) { double cc = 0.0; - if(tower->GetCrosswindConstraint(cc)) { + if(tower && tower->GetCrosswindConstraint(cc)) { if(orthopos.y() > cc) { //cout << "Turning to crosswind, distance from threshold = " << orthopos.y() << '\n'; leg = TURN1; @@ -884,7 +884,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { // turn 1000m out for now, taking other traffic into accout if(fabs(orthopos.x()) > 900) { double dd = 0.0; - if(tower->GetDownwindConstraint(dd)) { + if(tower && tower->GetDownwindConstraint(dd)) { if(fabs(orthopos.x()) > fabs(dd)) { //cout << "Turning to downwind, distance from centerline = " << fabs(orthopos.x()) << '\n'; leg = TURN2; @@ -930,7 +930,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { // For now we're assuming that we aim to follow the same glidepath regardless of wind. double d1; double d2; - CalculateSoD((tower->GetBaseConstraint(d1) ? d1 : -1000.0), (tower->GetDownwindConstraint(d2) ? d2 : 1000.0 * patternDirection), (patternDirection ? true : false)); + CalculateSoD(((tower && tower->GetBaseConstraint(d1)) ? d1 : -1000.0), ((tower && tower->GetDownwindConstraint(d2)) ? d2 : 1000.0 * patternDirection), (patternDirection ? true : false)); if(SoD.leg == DOWNWIND) { descending = (orthopos.y() < SoD.y ? true : false); } @@ -950,7 +950,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { if(orthopos.y() < -1000.0 + turn_radius) { //if(orthopos.y() < -980) { double bb = 0.0; - if(tower->GetBaseConstraint(bb)) { + if(tower && tower->GetBaseConstraint(bb)) { if(fabs(orthopos.y()) > fabs(bb)) { //cout << "Turning to base, distance from threshold = " << fabs(orthopos.y()) << '\n'; leg = TURN3; @@ -982,7 +982,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { double d1; // Make downwind leg position artifically large to avoid any chance of SoD being returned as // on downwind when we are already on base. - CalculateSoD((tower->GetBaseConstraint(d1) ? d1 : -1000.0), (10000.0 * patternDirection), (patternDirection ? true : false)); + CalculateSoD(((tower && tower->GetBaseConstraint(d1)) ? d1 : -1000.0), (10000.0 * patternDirection), (patternDirection ? true : false)); if(SoD.leg == BASE) { descending = (fabs(orthopos.y()) < fabs(SoD.y) ? true : false); } @@ -1207,10 +1207,11 @@ void FGAILocalTraffic::CalculateSoD(double base_leg_pos, double downwind_leg_pos void FGAILocalTraffic::TransmitPatternPositionReport(void) { // airport name + "traffic" + airplane callsign + pattern direction + pattern leg + rwy + ? - string trns = ""; + string trns; int code = 0; - - trns += tower->get_name(); + const string& apt_name = tower ? tower->get_name() : airportID; + + trns += apt_name; trns += " Traffic "; trns += plane.callsign; if(patternDirection == 1) { @@ -1249,10 +1250,10 @@ void FGAILocalTraffic::TransmitPatternPositionReport(void) { } trns += ConvertRwyNumToSpokenString(rwy.rwyID); - trns += " "; + trns += ' '; // And add the airport name again - trns += tower->get_name(); + trns += apt_name; pending_transmission = trns; ConditionalTransmit(60.0, code); // Assume a report of this leg will be invalid if we can't transmit within a minute. From e750dc368dde488ca42cd2b2cf0fa15e23ab0626 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 8 Nov 2009 13:41:03 +0000 Subject: [PATCH 35/62] John Denker: Together with previous patch, make view reference frame, view offset, and current view visible in property tree. Also some comments about the concepts behind these variables. --- src/Main/viewmgr.cxx | 120 ++++++++++++++++++++++++++++--------------- src/Main/viewmgr.hxx | 8 ++- 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 5f8485a68..6d48451c3 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -221,8 +221,8 @@ FGViewMgr::bind () fgTie(x("/sim/current-view/view_or_offset"), this, &FGViewMgr::getCurrentViewOrOffset); - fgTie(x("/sim/current-view/view1200"), this, - &FGViewMgr::getCurrentView1200); + fgTie(x("/sim/current-view/view_frame"), this, + &FGViewMgr::getCurrentViewFrame); SGPropertyNode *n = fgGetNode("/sim/current-view", true); n->tie("viewer-x-m", SGRawValuePointer<double>(&abs_viewer_position[0])); @@ -770,52 +770,88 @@ FGViewMgr::setViewAxisLat (double axis) axis_lat = axis; } -static const char* fmt("%6.3f ; %6.3f %6.3f %6.3f"); - -// current view orientation -// This is a rotation relative to the earth-centered (ec) -// refrence frame. -// However, the components of this quaternion are expressed -// in the OpenGL camera system i.e. x-right, y-up, z-back. -const char* FGViewMgr::getCurrentViewOrientation() const{ - return str(boost::format(fmt) - % current_view_orientation.w() - % current_view_orientation.x() - % current_view_orientation.y() - % current_view_orientation.z() ).c_str(); +// Convert a quat to a string. +// We assume the quat is being used as a rotor, so we +// coerce it to standard rotor form, making the scalar +// part non-negative, to eliminate double coverage of +// the rotation group. +// The format is "w ; x y z" with a semicolon separating +// the scalar part from the bivector components. +const char* format_rotor(const SGQuatd _quat){ + SGQuatd quat(_quat); + if (quat.w() < 0.) quat *= -1.; // remove double coverage + return str(boost::format("%6.3f ; %6.3f %6.3f %6.3f") + % quat.w() + % quat.x() + % quat.y() + % quat.z() ).c_str(); } -// This rotation takes you from the 12:00 direction -// i.e. body attitude -// to whatever the current view direction is. +// reference frame orientation. +// This is the view orientation you get when you have no +// view offset, i.e. the offset operator is the identity. +// +// For example, in the familiar "cockpit lookfrom" view, +// the reference frame is equal to the aircraft attitude, +// i.e. it is the view looking towards 12:00 straight ahead. +// +// FIXME: Somebody needs to figure out what is the reference +// frame view for the other view modes. +// +// Conceptually, this quat represents a rotation relative +// to the ECEF reference orientation, as described at +// http://www.av8n.com/physics/coords.htm#sec-orientation +// +// See the NOTE concerning reference orientations, below. +// +// The components of this quat are expressed in +// the conventional aviation basis set, +// i.e. x=forward, y=starboard, z=bottom +const char* FGViewMgr::getCurrentViewFrame() const{ + return format_rotor(current_view_orientation * conj(fsb2sta) + * conj(current_view_or_offset) ); +} + +// view offset. +// This rotation takes you from the aforementioned +// reference frame view orientation to whatever +// actual current view orientation is. +// // The components of this quaternion are expressed in -// the XYZ body frame. +// the conventional aviation basis set, +// i.e. x=forward, y=starboard, z=bottom const char* FGViewMgr::getCurrentViewOrOffset() const{ - return str(boost::format(fmt) - % current_view_or_offset.w() - % current_view_or_offset.x() - % current_view_or_offset.y() - % current_view_or_offset.z() ).c_str(); + return format_rotor(current_view_or_offset); } -// This rotates the conventional aviation XYZ body system -// i.e. x-forward, y-starboard, z-bottom -// to the OpenGL camera system -// i.e. x-right, y-up, z-back. -const SGQuatd q(-0.5, -0.5, 0.5, 0.5); - -// The current attitude of the aircraft, -// i.e. the 12:00 direction. -// The components of this quaternion are expressed in -// the GL camera frame. -const char* FGViewMgr::getCurrentView1200() const{ - SGQuatd view1200 = current_view_orientation - * conj(q) * conj(current_view_or_offset) * q; - return str(boost::format(fmt) - % view1200.w() - % view1200.x() - % view1200.y() - % view1200.z() ).c_str(); +// current view orientation. +// This is a rotation relative to the earth-centered (ec) +// reference frame. +// +// NOTE: Here we remove a factor of fsb2sta so that +// the components of this quat are displayed using the +// conventional ECEF basis set. This is *not* the way +// the view orientation is stored in the views[] array, +// but is easier for most people to understand. +// If we did not remove this factor of fsb2sta here and +// in getCurrentViewFrame, that would be equivalent to +// the following peculiar reference orientation: +// Suppose you are over the Gulf of Guinea, at (lat,lon) = (0,0). +// Then the reference frame orientation can be achieved via: +// -- The aircraft X-axis (nose) headed south. +// -- The aircraft Y-axis (starboard wingtip) pointing up. +// -- The aircraft Z-axis (belly) pointing west. +// To say the same thing in other words, and perhaps more to the +// point: If we use the OpenGL camera orientation conventions, +// i.e. Xprime=starboard, Yprime=top, Zprime=aft, then the +// aforementioned peculiar reference orientation at (lat,lon) +// = (0,0) can be described as: +// -- aircraft Xprime axis (starboard) pointed up +// -- aircraft Yprime axis (top) pointed east +// -- aircraft Zprime axis (aft) pointed north +// meaning the OpenGL axes are aligned with the ECEF axes. +const char* FGViewMgr::getCurrentViewOrientation() const{ + return format_rotor(current_view_orientation * conj(fsb2sta)); } void diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index f1a0eccd4..30f81bec9 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -122,7 +122,7 @@ private: // quaternion accessors: const char* getCurrentViewOrientation() const; const char* getCurrentViewOrOffset() const; - const char* getCurrentView1200() const; + const char* getCurrentViewFrame() const; bool stationary () const; @@ -139,5 +139,11 @@ private: }; +// This takes the conventional aviation XYZ body system +// i.e. x=forward, y=starboard, z=bottom +// which is widely used in FGFS +// and rotates it into the OpenGL camera system +// i.e. Xprime=starboard, Yprime=top, Zprime=aft. +const SGQuatd fsb2sta(-0.5, -0.5, 0.5, 0.5); #endif // _VIEWMGR_HXX From 81171348791b325db2393f072fcf8bd93277d20d Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore@redhat.com> Date: Mon, 9 Nov 2009 10:24:46 +0100 Subject: [PATCH 36/62] don't define constant objects in header files --- src/Main/viewmgr.cxx | 6 +++--- src/Main/viewmgr.hxx | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 6d48451c3..3a5777afd 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -808,7 +808,7 @@ const char* format_rotor(const SGQuatd _quat){ // the conventional aviation basis set, // i.e. x=forward, y=starboard, z=bottom const char* FGViewMgr::getCurrentViewFrame() const{ - return format_rotor(current_view_orientation * conj(fsb2sta) + return format_rotor(current_view_orientation * conj(fsb2sta()) * conj(current_view_or_offset) ); } @@ -832,7 +832,7 @@ const char* FGViewMgr::getCurrentViewOrOffset() const{ // the components of this quat are displayed using the // conventional ECEF basis set. This is *not* the way // the view orientation is stored in the views[] array, -// but is easier for most people to understand. +// but is easier for non-graphics hackers to understand. // If we did not remove this factor of fsb2sta here and // in getCurrentViewFrame, that would be equivalent to // the following peculiar reference orientation: @@ -851,7 +851,7 @@ const char* FGViewMgr::getCurrentViewOrOffset() const{ // -- aircraft Zprime axis (aft) pointed north // meaning the OpenGL axes are aligned with the ECEF axes. const char* FGViewMgr::getCurrentViewOrientation() const{ - return format_rotor(current_view_orientation * conj(fsb2sta)); + return format_rotor(current_view_orientation * conj(fsb2sta())); } void diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 30f81bec9..443cc33bb 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -144,6 +144,9 @@ private: // which is widely used in FGFS // and rotates it into the OpenGL camera system // i.e. Xprime=starboard, Yprime=top, Zprime=aft. -const SGQuatd fsb2sta(-0.5, -0.5, 0.5, 0.5); +inline const SGQuatd fsb2sta() +{ + return SGQuatd(-0.5, -0.5, 0.5, 0.5); +} #endif // _VIEWMGR_HXX From 2bc7dc685b35b489730ef36050a318b331c14977 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 9 Nov 2009 10:28:59 +0000 Subject: [PATCH 37/62] allow sound effects in the configuration file to be added to the 'avionics' sample group by setting '<type>avionics</type>'. --- src/Sound/fg_fx.cxx | 3 ++- src/Sound/fg_fx.hxx | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 4d879bff2..abf3a2678 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -47,6 +47,7 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : SGSampleGroup::_smgr = smgr; SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); + _avionics = _smgr->find("avionics", true); } @@ -91,7 +92,7 @@ FGFX::init() try { sound->init(globals->get_props(), node->getChild(i), this, - globals->get_fg_root()); + _avionics, globals->get_fg_root()); _sound.push_back(sound); } catch ( sg_exception &e ) { diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index 62e111076..8a004465c 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -57,6 +57,7 @@ public: private: + SGSharedPtr<SGSampleGroup> _avionics; std::vector<SGXmlSound *> _sound; bool last_pause; From d5b9f552dda1749e002967199ec9b79d1d02cb5c Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 9 Nov 2009 10:35:49 +0000 Subject: [PATCH 38/62] Add a description of the 'type' tag --- docs-mini/README.xmlsound | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs-mini/README.xmlsound b/docs-mini/README.xmlsound index de78a416c..23a725e02 100644 --- a/docs-mini/README.xmlsound +++ b/docs-mini/README.xmlsound @@ -128,6 +128,17 @@ Configuration description: in-transit: the sample plays continuously, while the property is changing its value. + + <type> + This defines the type os this sample: + + fx: this is the default type and doesn't need to be defined. + + avionics: sounds set to this time don't have a position and + orientation but are treated as if it's mounted to + the aircraft panel. it's up to the user to define + if it can always be heard or only when in cockpit + view. <volume> / <pitch> Volume or Pitch definition. Currently there may be up to 5 From db3a4b0753dbe60770a18a9681c580630c80dc53 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 9 Nov 2009 10:36:55 +0000 Subject: [PATCH 39/62] fix a typo --- docs-mini/README.xmlsound | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-mini/README.xmlsound b/docs-mini/README.xmlsound index 23a725e02..9fa920f89 100644 --- a/docs-mini/README.xmlsound +++ b/docs-mini/README.xmlsound @@ -134,7 +134,7 @@ Configuration description: fx: this is the default type and doesn't need to be defined. - avionics: sounds set to this time don't have a position and + avionics: sounds set to this type don't have a position and orientation but are treated as if it's mounted to the aircraft panel. it's up to the user to define if it can always be heard or only when in cockpit From 742aec2f32eb4afbdf2072ac0f4090d08ebbe72d Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 10 Nov 2009 14:29:25 +0000 Subject: [PATCH 40/62] Pass the north-east-down velocty directly to the sample_group and do the calculations there. --- src/Model/acmodel.cxx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 4df8f19f1..1da7e3759 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -132,16 +132,10 @@ FGAircraftModel::update (double dt) _roll->getDoubleValue()); _fx->set_orientation( orient ); - SGVec3d vel = SGVec3d( _speed_n->getFloatValue(), - _speed_e->getFloatValue(), - _speed_d->getFloatValue() ); - if ( vel[0] || vel[1] || vel[2] ) { - SGQuatd hlOr = SGQuatd::fromLonLat(position); - _velocity = 100.0 * toVec3f( hlOr.rotateBack( vel * SG_FEET_TO_METER ) ); - } - else - _velocity = SGVec3f::zeros(); - _fx->set_velocity( _velocity ); + SGVec3d vel = SGVec3d( _speed_n->getDoubleValue(), + _speed_e->getDoubleValue(), + _speed_d->getDoubleValue() ); + _fx->set_velocity( vel ); } From 769bac95e3dcb644684e95bcbbf53d9fd00fea41 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 11 Nov 2009 08:22:30 +0000 Subject: [PATCH 41/62] put the debugging quat strings as doubles under /sim/current-view/debug instead. --- src/Main/viewmgr.cxx | 101 ++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 3a5777afd..dd1299be9 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -28,7 +28,6 @@ #include "viewmgr.hxx" #include <string.h> // strcmp -#include <boost/format.hpp> #include <simgear/compiler.h> #include <simgear/sound/soundmgr_openal.hxx> @@ -163,9 +162,6 @@ typedef double (FGViewMgr::*double_getter)() const; void FGViewMgr::bind () { -// for automatic untying: -#define x(str) ((void)tied_props.push_back(str), str) - // these are bound to the current view properties fgTie("/sim/current-view/heading-offset-deg", this, &FGViewMgr::getViewHeadingOffset_deg, @@ -216,19 +212,41 @@ FGViewMgr::bind () &FGViewMgr::getNear_m, &FGViewMgr::setNear_m); fgSetArchivable("/sim/current-view/ground-level-nearplane-m"); - fgTie(x("/sim/current-view/view_orientation"), this, - &FGViewMgr::getCurrentViewOrientation); - fgTie(x("/sim/current-view/view_or_offset"), this, - &FGViewMgr::getCurrentViewOrOffset); - - fgTie(x("/sim/current-view/view_frame"), this, - &FGViewMgr::getCurrentViewFrame); - SGPropertyNode *n = fgGetNode("/sim/current-view", true); n->tie("viewer-x-m", SGRawValuePointer<double>(&abs_viewer_position[0])); n->tie("viewer-y-m", SGRawValuePointer<double>(&abs_viewer_position[1])); n->tie("viewer-z-m", SGRawValuePointer<double>(&abs_viewer_position[2])); +// for automatic untying: +#define x(str) ((void)tied_props.push_back(str), str) + + fgTie(x("/sim/current-view/debug/orientation-w"), this, + &FGViewMgr::getCurrentViewOrientation_w); + fgTie(x("/sim/current-view/debug/orientation-x"), this, + &FGViewMgr::getCurrentViewOrientation_x); + fgTie(x("/sim/current-view/debug/orientation-y"), this, + &FGViewMgr::getCurrentViewOrientation_y); + fgTie(x("/sim/current-view/debug/orientation-z"), this, + &FGViewMgr::getCurrentViewOrientation_z); + + fgTie(x("/sim/current-view/debug/orientation_offset-w"), this, + &FGViewMgr::getCurrentViewOrOffset_w); + fgTie(x("/sim/current-view/debug/orientation_offset-x"), this, + &FGViewMgr::getCurrentViewOrOffset_x); + fgTie(x("/sim/current-view/debug/orientation_offset-y"), this, + &FGViewMgr::getCurrentViewOrOffset_y); + fgTie(x("/sim/current-view/debug/orientation_offset-z"), this, + &FGViewMgr::getCurrentViewOrOffset_z); + + fgTie(x("/sim/current-view/debug/frame-w"), this, + &FGViewMgr::getCurrentViewFrame_w); + fgTie(x("/sim/current-view/debug/frame-x"), this, + &FGViewMgr::getCurrentViewFrame_x); + fgTie(x("/sim/current-view/debug/frame-y"), this, + &FGViewMgr::getCurrentViewFrame_y); + fgTie(x("/sim/current-view/debug/frame-z"), this, + &FGViewMgr::getCurrentViewFrame_z); + #undef x } @@ -770,23 +788,6 @@ FGViewMgr::setViewAxisLat (double axis) axis_lat = axis; } -// Convert a quat to a string. -// We assume the quat is being used as a rotor, so we -// coerce it to standard rotor form, making the scalar -// part non-negative, to eliminate double coverage of -// the rotation group. -// The format is "w ; x y z" with a semicolon separating -// the scalar part from the bivector components. -const char* format_rotor(const SGQuatd _quat){ - SGQuatd quat(_quat); - if (quat.w() < 0.) quat *= -1.; // remove double coverage - return str(boost::format("%6.3f ; %6.3f %6.3f %6.3f") - % quat.w() - % quat.x() - % quat.y() - % quat.z() ).c_str(); -} - // reference frame orientation. // This is the view orientation you get when you have no // view offset, i.e. the offset operator is the identity. @@ -807,10 +808,19 @@ const char* format_rotor(const SGQuatd _quat){ // The components of this quat are expressed in // the conventional aviation basis set, // i.e. x=forward, y=starboard, z=bottom -const char* FGViewMgr::getCurrentViewFrame() const{ - return format_rotor(current_view_orientation * conj(fsb2sta()) - * conj(current_view_or_offset) ); +double FGViewMgr::getCurrentViewFrame_w() const{ + return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).w(); } +double FGViewMgr::getCurrentViewFrame_x() const{ + return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).x(); +} +double FGViewMgr::getCurrentViewFrame_y() const{ + return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).y(); +} +double FGViewMgr::getCurrentViewFrame_z() const{ + return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).z(); +} + // view offset. // This rotation takes you from the aforementioned @@ -820,9 +830,19 @@ const char* FGViewMgr::getCurrentViewFrame() const{ // The components of this quaternion are expressed in // the conventional aviation basis set, // i.e. x=forward, y=starboard, z=bottom -const char* FGViewMgr::getCurrentViewOrOffset() const{ - return format_rotor(current_view_or_offset); +double FGViewMgr::getCurrentViewOrOffset_w() const{ + return current_view_or_offset.w(); } +double FGViewMgr::getCurrentViewOrOffset_x() const{ + return current_view_or_offset.x(); +} +double FGViewMgr::getCurrentViewOrOffset_y() const{ + return current_view_or_offset.y(); +} +double FGViewMgr::getCurrentViewOrOffset_z() const{ + return current_view_or_offset.z(); +} + // current view orientation. // This is a rotation relative to the earth-centered (ec) @@ -850,8 +870,17 @@ const char* FGViewMgr::getCurrentViewOrOffset() const{ // -- aircraft Yprime axis (top) pointed east // -- aircraft Zprime axis (aft) pointed north // meaning the OpenGL axes are aligned with the ECEF axes. -const char* FGViewMgr::getCurrentViewOrientation() const{ - return format_rotor(current_view_orientation * conj(fsb2sta())); +double FGViewMgr::getCurrentViewOrientation_w() const{ + return (current_view_orientation * conj(fsb2sta())).w(); +} +double FGViewMgr::getCurrentViewOrientation_x() const{ + return (current_view_orientation * conj(fsb2sta())).x(); +} +double FGViewMgr::getCurrentViewOrientation_y() const{ + return (current_view_orientation * conj(fsb2sta())).y(); +} +double FGViewMgr::getCurrentViewOrientation_z() const{ + return (current_view_orientation * conj(fsb2sta())).z(); } void From 96b7939947e00ae9f229d8818bba424b5ecc2157 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 11 Nov 2009 13:35:58 +0000 Subject: [PATCH 42/62] put the debugging quat strings as doubles under /sim/current-view/debug instead. --- src/Main/viewmgr.hxx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 443cc33bb..c296b7155 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -119,10 +119,20 @@ private: void setViewAxisLat (double axis); int getView () const; void setView (int newview); -// quaternion accessors: - const char* getCurrentViewOrientation() const; - const char* getCurrentViewOrOffset() const; - const char* getCurrentViewFrame() const; + +// quaternion accessors, for debugging: + double getCurrentViewOrientation_w() const; + double getCurrentViewOrientation_x() const; + double getCurrentViewOrientation_y() const; + double getCurrentViewOrientation_z() const; + double getCurrentViewOrOffset_w() const; + double getCurrentViewOrOffset_x() const; + double getCurrentViewOrOffset_y() const; + double getCurrentViewOrOffset_z() const; + double getCurrentViewFrame_w() const; + double getCurrentViewFrame_x() const; + double getCurrentViewFrame_y() const; + double getCurrentViewFrame_z() const; bool stationary () const; From 0578b06a0c58f7c206ec23819a1d3b9f97ae960b Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 12 Nov 2009 20:42:24 +0000 Subject: [PATCH 43/62] temporarily remove listener (viewer) and source offsets. they mess things up --- src/Main/viewer.hxx | 1 + src/Main/viewmgr.cxx | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index aa5fb1212..7005e661f 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -119,6 +119,7 @@ public: // orientation rotations listed below. This has the effect of the // eye moving around and "looking at" the object (model) from // different angles. + virtual SGVec3d getOffset_m () const { return _offset_m; } virtual double getXOffset_m () const { return _offset_m.x(); } virtual double getYOffset_m () const { return _offset_m.y(); } virtual double getZOffset_m () const { return _offset_m.z(); } diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index dd1299be9..a0494b080 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -338,7 +338,8 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position( abs_viewer_position ); + smgr->set_position( SGVec3d::fromGeod(loop_view->getPosition()) ); + smgr->set_position_offset( loop_view->getOffset_m() ); smgr->set_orientation( current_view_orientation ); // get the model velocity From 33058511def350653ea01459a2161a3533531555 Mon Sep 17 00:00:00 2001 From: jmt <jmt> Date: Sat, 14 Nov 2009 11:10:34 +0000 Subject: [PATCH 44/62] Dave Perry: Allows using a nasal filter to smoothly park the gs needle when out of range or frequency changes to a station w/o gs. --- src/Instrumentation/navradio.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Instrumentation/navradio.cxx b/src/Instrumentation/navradio.cxx index 4dace88a0..31eb2f461 100644 --- a/src/Instrumentation/navradio.cxx +++ b/src/Instrumentation/navradio.cxx @@ -575,6 +575,8 @@ void FGNavRadio::updateGlideSlope(double dt, const SGVec3d& aircraft, double sig if (!_gs || !inrange_node->getBoolValue()) { gs_dist_node->setDoubleValue( 0.0 ); gs_inrange_node->setBoolValue(false); + _gsNeedleDeflection = 0.0; + _gsNeedleDeflectionNorm = 0.0; return; } @@ -584,6 +586,8 @@ void FGNavRadio::updateGlideSlope(double dt, const SGVec3d& aircraft, double sig gs_inrange_node->setBoolValue(gsInRange); if (!gsInRange) { + _gsNeedleDeflection = 0.0; + _gsNeedleDeflectionNorm = 0.0; return; } From 97db69cf8f21ec54ce628c71141808d8555501e6 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 16 Nov 2009 13:36:25 +0000 Subject: [PATCH 45/62] restore listener position with offset --- src/Main/viewmgr.cxx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index a0494b080..dd1299be9 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -338,8 +338,7 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position( SGVec3d::fromGeod(loop_view->getPosition()) ); - smgr->set_position_offset( loop_view->getOffset_m() ); + smgr->set_position( abs_viewer_position ); smgr->set_orientation( current_view_orientation ); // get the model velocity From 934ce52a235cda3827866f64a9af492f2ea1e63e Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 19 Nov 2009 15:28:37 +0000 Subject: [PATCH 46/62] Tie samplegroup 'avionics' to the listener, just in case no other device is created that does it. --- src/Sound/fg_fx.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index abf3a2678..d2addc66d 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -48,6 +48,7 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); _avionics = _smgr->find("avionics", true); + _avionics->tie_to_listener(); } From 3d19352f13c2258cfdc6c9cbd25c5bed98b156fe Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 23 Nov 2009 09:35:59 +0000 Subject: [PATCH 47/62] proper listener velocity calculation, this has no effect yet but is required when other models start emitting sounds. --- src/Main/viewmgr.cxx | 6 +++--- src/Model/acmodel.cxx | 8 ++++---- src/Model/acmodel.hxx | 4 ++-- src/Sound/sample_queue.cxx | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index dd1299be9..270c579e0 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -338,15 +338,15 @@ FGViewMgr::update (double dt) // update audio listener values // set the viewer posotion in Cartesian coordinates in meters - smgr->set_position( abs_viewer_position ); + smgr->set_position( abs_viewer_position, loop_view->getPosition() ); smgr->set_orientation( current_view_orientation ); // get the model velocity - SGVec3f velocity = SGVec3f::zeros(); + SGVec3d velocity = SGVec3d::zeros(); if ( !stationary() ) { velocity = globals->get_aircraft_model()->getVelocity(); } - smgr->set_velocity(velocity); + smgr->set_velocity( velocity ); } void diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 1da7e3759..2df6e0abf 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -132,10 +132,10 @@ FGAircraftModel::update (double dt) _roll->getDoubleValue()); _fx->set_orientation( orient ); - SGVec3d vel = SGVec3d( _speed_n->getDoubleValue(), - _speed_e->getDoubleValue(), - _speed_d->getDoubleValue() ); - _fx->set_velocity( vel ); + _velocity = SGVec3d( _speed_n->getDoubleValue(), + _speed_e->getDoubleValue(), + _speed_d->getDoubleValue() ); + _fx->set_velocity( _velocity ); } diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index da3c844f5..59e6034dd 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -39,12 +39,12 @@ public: virtual void unbind (); virtual void update (double dt); virtual SGModelPlacement * get3DModel() { return _aircraft; } - virtual SGVec3f& getVelocity() { return _velocity; } + virtual SGVec3d& getVelocity() { return _velocity; } private: SGModelPlacement * _aircraft; - SGVec3f _velocity; + SGVec3d _velocity; SGSharedPtr<FGFX> _fx; SGPropertyNode_ptr _lon; diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx index 9d7140165..863cbcbdc 100644 --- a/src/Sound/sample_queue.cxx +++ b/src/Sound/sample_queue.cxx @@ -44,6 +44,7 @@ FGSampleQueue::FGSampleQueue ( SGSoundMgr *smgr, const string &refname ) : { SGSampleGroup::_smgr = smgr; SGSampleGroup::_smgr->add(this, refname); + SGSampleGroup::_refname = refname; } From ef4814599d3985164b58c817616d80235ca70c99 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sat, 28 Nov 2009 10:42:52 +0000 Subject: [PATCH 48/62] * Fix --disable-sound * Add a new command line option: --sound-device="" This makes OpenAL use the sepcified audio device instead of the default output device. (Look for playback devices when calling openal-info of alcinfo) --- src/Main/fg_init.cxx | 2 +- src/Main/options.cxx | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index cf6c86b70..3d253091d 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1453,7 +1453,7 @@ bool fgInitSubsystems() { //////////////////////////////////////////////////////////////////// globals->get_soundmgr()->bind(); - globals->get_soundmgr()->init(); + globals->get_soundmgr()->init(fgGetString("/sim/sound/device-name", NULL)); //////////////////////////////////////////////////////////////////// // Initialize the property interpolator subsystem. Put into the INIT diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 73ebf0627..2651965ff 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1291,8 +1291,9 @@ struct OptionDesc { {"enable-hud", false, OPTION_BOOL, "/sim/hud/visibility", true, "", 0 }, {"disable-panel", false, OPTION_BOOL, "/sim/panel/visibility", false, "", 0 }, {"enable-panel", false, OPTION_BOOL, "/sim/panel/visibility", true, "", 0 }, - {"disable-sound", false, OPTION_BOOL, "/sim/sound/enabled", true, "", 0 }, - {"enable-sound", false, OPTION_BOOL, "/sim/sound/enabled", false, "", 0 }, + {"disable-sound", false, OPTION_BOOL, "/sim/sound/enabled", false, "", 0 }, + {"enable-sound", false, OPTION_BOOL, "/sim/sound/enabled", true, "", 0 }, + {"sound-device", true, OPTION_STRING, "/sim/sound/device-name", false, "", 0 }, {"airport", true, OPTION_STRING, "/sim/presets/airport-id", false, "", 0 }, {"runway", true, OPTION_FUNC, "", false, "", fgOptRunway }, {"vor", true, OPTION_FUNC, "", false, "", fgOptVOR }, From 3abb7afa4560296c3d44d7e2ebd51e34a1a02f9b Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sat, 28 Nov 2009 13:33:54 +0000 Subject: [PATCH 49/62] List all available playback devices under '/sim/sound/devcies' --- src/Main/fg_init.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 3d253091d..6e99a68bc 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1455,6 +1455,14 @@ bool fgInitSubsystems() { globals->get_soundmgr()->bind(); globals->get_soundmgr()->init(fgGetString("/sim/sound/device-name", NULL)); + vector <const char*>devices = + globals->get_soundmgr()->get_available_devices(); + for (int i=0; i<devices.size(); i++) { + SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true); + p->setStringValue(devices[i]); + } + devices.clear(); + //////////////////////////////////////////////////////////////////// // Initialize the property interpolator subsystem. Put into the INIT // group because the "nasal" subsystem may need it at GENERAL take-down. From 3a4892cedea92e66f0763fc2008896154498f691 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 29 Nov 2009 10:24:47 +0000 Subject: [PATCH 50/62] New Property layout: /sim/sound/enabled enable/disable the use of OpenAL /sin/sound/pause master mute, effects all SampleGroups /sim/sound/volume master volume /sim/sound/effects/enabled enable/disable (mute) sound fx /sim/sound/effects/volume effects volume /sim/sound/chatter/enabled enable/disable (mute) atc chatter /sim/sound/chatter/volume chatter (sample queue) volume --- src/Main/main.cxx | 30 +++++++++++++++++++++--------- src/Sound/fg_fx.cxx | 22 ++++++++++++---------- src/Sound/fg_fx.hxx | 4 ++-- src/Sound/sample_queue.cxx | 22 ++++++++++++---------- src/Sound/sample_queue.hxx | 4 ++-- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 66bf3c6d8..896a38bfe 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -480,7 +480,23 @@ static void fgMainLoop( void ) { // Update the sound manager last so it can use the CPU while the GPU // is processing the scenery (doubled the frame-rate for me) -EMH- #ifdef ENABLE_AUDIO_SUPPORT - globals->get_soundmgr()->update(delta_time_sec); + static SGPropertyNode *sound_pause = fgGetNode("/sim/sound/pause"); + static SGSoundMgr *smgr = globals->get_soundmgr(); + static bool smgr_suspend = false; + if (smgr_suspend != sound_pause->getBoolValue()) { + if (smgr_suspend == false) { // request to suspend + smgr->suspend(); + } else { + smgr->resume(); + } + smgr_suspend = sound_pause->getBoolValue(); + } + + if (smgr_suspend == false) { + static SGPropertyNode *volume = fgGetNode("/sim/sound/volume"); + smgr->set_volume(volume->getFloatValue()); + smgr->update(delta_time_sec); + } #endif // END Tile Manager udpates @@ -488,15 +504,11 @@ static void fgMainLoop( void ) { if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded() && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); -#ifdef ENABLE_AUDIO_SUPPORT - if (fgGetBool("/sim/sound/enabled") == true) { - float volume = fgGetFloat("/sim/sound/volume"); - globals->get_soundmgr()->set_volume(volume); - globals->get_soundmgr()->activate(); + if (fgGetBool("/sim/sound/enabled")) { + smgr->activate(); + } else { + smgr->stop(); } - else - globals->get_soundmgr()->stop(); -#endif } fgRequestRedraw(); diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index d2addc66d..831375454 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -39,16 +39,18 @@ #include <simgear/sound/xmlsound.hxx> FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : - last_pause( false ), + last_enabled( true ), last_volume( 0.0 ), - _pause( fgGetNode("/sim/sound/pause") ), - _volume( fgGetNode("/sim/sound/volume") ) + _enabled( fgGetNode("/sim/sound/effects/enabled", true) ), + _volume( fgGetNode("/sim/sound/effects/volume", true) ) { SGSampleGroup::_smgr = smgr; SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); _avionics = _smgr->find("avionics", true); _avionics->tie_to_listener(); + _enabled->setBoolValue(true); + _volume->setFloatValue(1.0); } @@ -116,17 +118,17 @@ FGFX::reinit() void FGFX::update (double dt) { - bool new_pause = _pause->getBoolValue(); - if ( new_pause != last_pause ) { - if ( new_pause ) { - suspend(); - } else { + bool new_enabled = _enabled->getBoolValue(); + if ( new_enabled != last_enabled ) { + if ( new_enabled ) { resume(); + } else { + suspend(); } - last_pause = new_pause; + last_enabled = new_enabled; } - if ( !new_pause ) { + if ( new_enabled ) { double volume = _volume->getDoubleValue(); if ( volume != last_volume ) { set_volume( volume ); diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index 8a004465c..f28d3677b 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -60,10 +60,10 @@ private: SGSharedPtr<SGSampleGroup> _avionics; std::vector<SGXmlSound *> _sound; - bool last_pause; + bool last_enabled; double last_volume; - SGPropertyNode_ptr _pause; + SGPropertyNode_ptr _enabled; SGPropertyNode_ptr _volume; }; diff --git a/src/Sound/sample_queue.cxx b/src/Sound/sample_queue.cxx index 863cbcbdc..e5c2293a6 100644 --- a/src/Sound/sample_queue.cxx +++ b/src/Sound/sample_queue.cxx @@ -37,14 +37,16 @@ #include <simgear/sound/sample_openal.hxx> FGSampleQueue::FGSampleQueue ( SGSoundMgr *smgr, const string &refname ) : - last_pause( false ), + last_enabled( true ), last_volume( 0.0 ), - _pause( fgGetNode("/sim/sound/pause") ), - _volume( fgGetNode("/sim/sound/volume") ) + _enabled( fgGetNode("/sim/sound/chatter/enabled", true) ), + _volume( fgGetNode("/sim/sound/chatter/volume", true) ) { SGSampleGroup::_smgr = smgr; SGSampleGroup::_smgr->add(this, refname); SGSampleGroup::_refname = refname; + _enabled->setBoolValue(true); + _volume->setFloatValue(1.0); } @@ -61,17 +63,17 @@ void FGSampleQueue::update (double dt) { // command sound manger - bool new_pause = _pause->getBoolValue(); - if ( new_pause != last_pause ) { - if ( new_pause ) { - suspend(); - } else { + bool new_enabled = _enabled->getBoolValue(); + if ( new_enabled != last_enabled ) { + if ( new_enabled ) { resume(); + } else { + suspend(); } - last_pause = new_pause; + last_enabled = new_enabled; } - if ( !new_pause ) { + if ( new_enabled ) { double volume = _volume->getDoubleValue(); if ( volume != last_volume ) { set_volume( volume ); diff --git a/src/Sound/sample_queue.hxx b/src/Sound/sample_queue.hxx index 88b30ae75..db3d9c785 100644 --- a/src/Sound/sample_queue.hxx +++ b/src/Sound/sample_queue.hxx @@ -57,10 +57,10 @@ private: std::queue< SGSharedPtr<SGSoundSample> > _messages; - bool last_pause; + bool last_enabled; double last_volume; - SGPropertyNode_ptr _pause; + SGPropertyNode_ptr _enabled; SGPropertyNode_ptr _volume; }; From b4b3f62717bcef9a8a9d77ec8b64fbeab3a36990 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Sun, 29 Nov 2009 18:08:46 +0000 Subject: [PATCH 51/62] add alcinfo instead. --- tests/Makefile.am | 6 +- tests/al-info.c | 114 ---------------- tests/alcinfo.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+), 117 deletions(-) delete mode 100644 tests/al-info.c create mode 100644 tests/alcinfo.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 69612dbef..57a0bd77c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = est-epsilon gl-info al-info +bin_PROGRAMS = est-epsilon gl-info alcinfo noinst_PROGRAMS = test-gethostname test-mktime test-text test-up test-env-map @@ -8,8 +8,8 @@ est_epsilon_LDADD = $(opengl_LIBS) gl_info_SOURCES = gl-info.c gl_info_LDADD = $(opengl_LIBS) -al_info_SOURCES = al-info.c -al_info_LDADD = $(openal_LIBS) +alcinfo_SOURCES = alcinfo.c +alcinfo_LDADD = $(openal_LIBS) test_env_map_SOURCES = test-env-map.cxx test_env_map_LDADD = $(opengl_LIBS) diff --git a/tests/al-info.c b/tests/al-info.c deleted file mode 100644 index 13c68f204..000000000 --- a/tests/al-info.c +++ /dev/null @@ -1,114 +0,0 @@ - -#include <stdio.h> - -#ifdef __APPLE__ -# include <OpenAL/al.h> -# include <OpenAL/alc.h> -#else -# include <AL/al.h> -# include <AL/alc.h> -# ifndef __CYGWIN__ -# include <AL/alext.h> -# endif -#endif - -#ifndef AL_VERSION_1_1 -# ifdef __APPLE__ -# include <OpenAL/altypes.h> -# include <OpenAL/alctypes.h> -#else -# include <AL/altypes.h> -# include <AL/alctypes.h> -# endif -#endif - -#define MAX_DATA 16 - -int main() -{ - ALCint data[MAX_DATA]; - ALCdevice *device = NULL; - ALCcontext *context = NULL; - const ALchar *s; - ALCenum error; - - device = alcOpenDevice(NULL); - if (device == NULL) - { - printf("No default audio device available.\n"); - return -1; - } - context = alcCreateContext(device, NULL); - if (context == NULL) - { - printf("Could not create a valid context.\n"); - return -2; - } - alcMakeContextCurrent(context); - - s = alGetString(AL_VENDOR); - printf("AL_VENDOR = \"%s\"\n", s); - - s = alGetString(AL_RENDERER); - printf("AL_RENDERER = \"%s\"\n", s); - - s = alGetString(AL_VERSION); - printf("AL_VERSION = \"%s\"\n", s); - - s = alGetString(AL_EXTENSIONS); - printf("AL_EXTENSIONS = \"%s\"\n", s); - - alcGetError(device); - - printf("\n"); - if (alcIsExtensionPresent(NULL, (const ALchar *)"ALC_ENUMERATION_EXT") == AL_TRUE) - { - s = alcGetString(NULL, ALC_DEVICE_SPECIFIER); - printf("ALC_DEVICE_SPECIFIER = \"%s\"\n", s); - } - - alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, data); - printf("ALC_MAJOR_VERSION = %i\n", *data); - alcGetIntegerv(device, ALC_MINOR_VERSION, 1, data); - printf("ALC_MINOR_VERSION = %i\n", *data); - - s = alcGetString(device, ALC_EXTENSIONS); - printf("ALC_EXTENSIONS = \"%s\"\n", s); - - if ((error = alcGetError(device))) - { - printf("Error #%i occured\n", error); - return error; - } - - s = alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER); - printf("ALC_DEFAULT_DEVICE_SPECIFIER = \"%s\"\n", s); - - if ((error = alcGetError(device))) - { - printf("Error #%i occured\n", error); - return error; - } - -#if 0 - alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &i); - printf("ALC attributes(%i): ", i); - - alcGetIntegerv(device, ALC_ALL_ATTRIBUTES, i, data); - for (j=0; j<i; j++) - { - printf("%i ", data[j]); - } - printf("\n"); - - if ((error = alcGetError(device))) - { - printf("Error #%i occured\n", error); - return error; - } -#endif - - alcCloseDevice(device); - - return 0; -} diff --git a/tests/alcinfo.c b/tests/alcinfo.c new file mode 100644 index 000000000..1d85ddd68 --- /dev/null +++ b/tests/alcinfo.c @@ -0,0 +1,331 @@ +/* -*- mode: C; tab-width:8; c-basic-offset:8 -*- + * vi:set ts=8: + * + * alcinfo.x + * + * alcinfo display info about a ALC extension and OpenAL renderer + * + * This file is in the Public Domain and comes with no warranty. + * Erik Hofman <erik@ehofman.com> + * + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef __APPLE__ +# include <OpenAL/al.h> +# include <OpenAL/alc.h> +#else +# include <AL/al.h> +# include <AL/alc.h> +# include <AL/alext.h> +#endif + +#ifndef AL_VERSION_1_1 +# ifdef __APPLE__ +# include <OpenAL/altypes.h> +# include <OpenAL/alctypes.h> +#else +# include <AL/altypes.h> +# include <AL/alctypes.h> +# endif +#endif + +#include <string.h> +#include <stdio.h> + +#define MAX_DATA 16 +static const int indentation = 4; +static const int maxmimumWidth = 79; + +void printExtensions (const char *, char, const char *); +void displayDevices(const char *, const char *); +char *getDeviceName(int, char **); +void testForError(void *, char *); +void testForALCError(ALCdevice *); + +int main(int argc, char **argv) +{ + ALCint data[MAX_DATA]; + ALCdevice *device = NULL; + ALCcontext *context = NULL; + ALenum error; + char *s; + + if (alcIsExtensionPresent(NULL, "ALC_enumeration_EXT") == AL_TRUE) + { + if (alcIsExtensionPresent(NULL, "ALC_enumerate_all_EXT") == AL_FALSE) + s = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER); + else + s = (char *)alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); + displayDevices("output", s); + + s = (char *)alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); + displayDevices("input", s); + } + + s = getDeviceName(argc, argv); + device = alcOpenDevice(s); + testForError(device, "Audio device not available."); + + context = alcCreateContext(device, NULL); + testForError(context, "Unable to create a valid context."); + + alcMakeContextCurrent(context); + testForALCError(device); + + s = (char *)alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER); + printf("default output device: %s\n", s); + testForALCError(device); + + error = alcIsExtensionPresent(device, "ALC_EXT_capture"); + if (error) + { + s = (char *)alcGetString(device, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); + printf("default input device: %s\n", s); + testForALCError(device); + } + printf("capture support: %s\n", (error) ? "yes" : "no"); + + alcGetIntegerv(device, ALC_FREQUENCY, 1, data); + printf("mixer frequency: %u hz\n", data[0]); + testForError(device, "invalid context"); + + alcGetIntegerv(device, ALC_REFRESH, 1, data+1); + printf("refresh rate : %u hz\n", data[0]/data[1]); + testForError(device, "invalid context"); + + data[0] = 0; + alcGetIntegerv(device, ALC_MONO_SOURCES, 1, data); + printf("supported sources; mono: %u, ", data[0]); + testForError(device, "invalid context"); + + data[0] = 0; + alcGetIntegerv(device, ALC_STEREO_SOURCES, 1, data); + printf("stereo: %u\n", data[0]); + testForError(device, "invalid context"); + + printf("ALC version: "); + alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, data); + printf("%i.", *data); + alcGetIntegerv(device, ALC_MINOR_VERSION, 1, data); + printf("%i\n", *data); + testForALCError(device); + + s = (char *)alcGetString(device, ALC_EXTENSIONS); + printExtensions ("ALC extensions", ' ', s); + testForALCError(device); + + s = (char *)alGetString(AL_VENDOR); + error = alGetError(); + if ((error = alGetError()) != AL_NO_ERROR) + printf("Error #%x: %s\n", error, alGetString(error)); + else + printf("OpenAL vendor string: %s\n", s); + + s = (char *)alGetString(AL_RENDERER); + if ((error = alGetError()) != AL_NO_ERROR) + printf("Error #%x: %s\n", error, alGetString(error)); + else + printf("OpenAL renderer string: %s\n", s); + + s = (char *)alGetString(AL_VERSION); + if ((error = alGetError()) != AL_NO_ERROR) + printf("Error #%x: %s\n", error, alGetString(error)); + else if (!s) + printf("Quering AL_VERSION returned NULL pointer!\n"); + else + printf("OpenAL version string: %s\n", s); + + s = (char *)alGetString(AL_EXTENSIONS); + printExtensions ("OpenAL extensions", ' ', s); + testForALCError(device); + +/* alut testing mechanism */ + context = alcGetCurrentContext(); + if (context == NULL) + { + printf("Error: no current context\n"); + } + else + { + if (alGetError () != AL_NO_ERROR) + { + printf("Alert: AL error on entry\n"); + } + else + { + if (alcGetError (alcGetContextsDevice (context)) != ALC_NO_ERROR) + { + printf("Alert: ALC error on entry\n"); + } + } + } +/* end of alut test */ + + + if (alcMakeContextCurrent(NULL) == 0) + printf("alcMakeContextCurrent failed.\n"); + + device = alcGetContextsDevice(context); + alcDestroyContext(context); + testForALCError(device); + + if (alcCloseDevice(device) == 0) + printf("alcCloseDevice failed.\n"); + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +void +printChar (int c, int *width) +{ + putchar (c); + *width = (c == '\n') ? 0 : (*width + 1); +} + +void +indent (int *width) +{ + int i; + for (i = 0; i < indentation; i++) + { + printChar (' ', width); + } +} + +void +printExtensions (const char *header, char separator, const char *extensions) +{ + int width = 0, start = 0, end = 0; + + printf ("%s:\n", header); + if (extensions == NULL || extensions[0] == '\0') + { + return; + } + + indent (&width); + while (1) + { + if (extensions[end] == separator || extensions[end] == '\0') + { + if (width + end - start + 2 > maxmimumWidth) + { + printChar ('\n', &width); + indent (&width); + } + while (start < end) + { + printChar (extensions[start], &width); + start++; + } + if (extensions[end] == '\0') + { + break; + } + start++; + end++; + if (extensions[end] == '\0') + { + break; + } + printChar (',', &width); + printChar (' ', &width); + } + end++; + } + printChar ('\n', &width); +} + +char * +getCommandLineOption(int argc, char **argv, char *option) +{ + int slen = strlen(option); + char *rv = 0; + int i; + + for (i=0; i<argc; i++) + { + if (strncmp(argv[i], option, slen) == 0) + { + i++; + if (i<argc) rv = argv[i]; + } + } + + return rv; +} + +char * +getDeviceName(int argc, char **argv) +{ + static char devname[255]; + int len = 255; + char *s; + + s = getCommandLineOption(argc, argv, "-d"); + if (s) + { + strncpy((char *)&devname, s, len); + len -= strlen(s); + + s = getCommandLineOption(argc, argv, "-r"); + if (s) + { + strncat((char *)&devname, " on ", len); + len -= 4; + + strncat((char *)&devname, s, len); + } + s = (char *)&devname; + } + + return s; +} + +void +displayDevices(const char *type, const char *list) +{ + ALCchar *ptr, *nptr; + + ptr = (ALCchar *)list; + printf("list of all available %s devices:\n", type); + if (!list) + { + printf("none\n"); + } + else + { + nptr = ptr; + while (*(nptr += strlen(ptr)+1) != 0) + { + printf(" %s\n", ptr); + ptr = nptr; + } + printf(" %s\n", ptr); + } +} + +void +testForError(void *p, char *s) +{ + if (p == NULL) + { + printf("\nError: %s\n\n", s); + exit(-1); + } +} + +void +testForALCError(ALCdevice *device) +{ + ALenum error; + error = alcGetError(device); + if (error != ALC_NO_ERROR) + printf("\nALC Error %x occurred: %s\n", error, alcGetString(device, error)); +} From a3b66adf51cd70578d1b5e6283b0e7475fb379fd Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 30 Nov 2009 08:42:29 +0000 Subject: [PATCH 52/62] add a new command line option: --show-sound-devices --- src/Main/options.cxx | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 2651965ff..b46424e53 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -45,6 +45,7 @@ #include <simgear/misc/sgstream.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/scene/material/mat.hxx> +#include <simgear/sound/soundmgr_openal.hxx> // #include <Include/general.hxx> // #include <Airports/simple.hxx> @@ -81,7 +82,8 @@ enum FG_OPTIONS_ERROR = 2, FG_OPTIONS_EXIT = 3, FG_OPTIONS_VERBOSE_HELP = 4, - FG_OPTIONS_SHOW_AIRCRAFT = 5 + FG_OPTIONS_SHOW_AIRCRAFT = 5, + FG_OPTIONS_SHOW_SOUND_DEVICES = 6 }; static double @@ -1503,6 +1505,8 @@ parse_option (const string& arg) return(FG_OPTIONS_VERBOSE_HELP); } else if ( arg.find( "--show-aircraft") == 0) { return(FG_OPTIONS_SHOW_AIRCRAFT); + } else if ( arg.find( "--show-sound-devices") == 0) { + return(FG_OPTIONS_SHOW_SOUND_DEVICES); } else if ( arg.find( "--prop:" ) == 0 ) { if (!set_property(arg.substr(7))) { SG_LOG( SG_GENERAL, SG_ALERT, "Bad property assignment: " << arg ); @@ -1618,11 +1622,20 @@ fgParseArgs (int argc, char **argv) verbose = true; else if (result == FG_OPTIONS_SHOW_AIRCRAFT) { - fgOptLogLevel( "alert" ); - SGPath path( globals->get_fg_root() ); - path.append("Aircraft"); - fgShowAircraft(path, true); - exit(0); + fgOptLogLevel( "alert" ); + SGPath path( globals->get_fg_root() ); + path.append("Aircraft"); + fgShowAircraft(path, true); + exit(0); + + } else if (result == FG_OPTIONS_SHOW_SOUND_DEVICES) { + SGSoundMgr smgr; + vector <const char*>devices = smgr.get_available_devices(); + for (int i=0; i<devices.size(); i++) { + printf("%i. \"%s\"\n", i, devices[i]); + } + devices.clear(); + exit(0); } else if (result == FG_OPTIONS_EXIT) From 64de526267241a4c2455873b6e9803d57fff4c46 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 30 Nov 2009 09:31:55 +0000 Subject: [PATCH 53/62] Fix for older OpenAL versions. --- tests/alcinfo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/alcinfo.c b/tests/alcinfo.c index 1d85ddd68..acc40a22d 100644 --- a/tests/alcinfo.c +++ b/tests/alcinfo.c @@ -33,9 +33,14 @@ # endif #endif +#include <stdlib.h> #include <string.h> #include <stdio.h> +#ifndef ALC_ALL_DEVICES_SPECIFIER +# define ALC_ALL_DEVICES_SPECIFIER 0x1013 +#endif + #define MAX_DATA 16 static const int indentation = 4; static const int maxmimumWidth = 79; From fde1a925feb8ccc50e88e3fbe72a0863625de2a5 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 30 Nov 2009 12:05:20 +0000 Subject: [PATCH 54/62] Change of thoughts since it makes life easier: /sim/sound/working enable/disable the use of OpenAL /sin/sound/enabled master mute/unmute --- src/Instrumentation/marker_beacon.cxx | 4 ++-- src/Instrumentation/marker_beacon.hxx | 2 +- src/Main/fg_props.cxx | 2 +- src/Main/main.cxx | 14 +++++++------- src/Main/options.cxx | 6 +++--- src/Sound/voice.cxx | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Instrumentation/marker_beacon.cxx b/src/Instrumentation/marker_beacon.cxx index d2e9774b7..c9f7c9a34 100644 --- a/src/Instrumentation/marker_beacon.cxx +++ b/src/Instrumentation/marker_beacon.cxx @@ -100,7 +100,7 @@ FGMarkerBeacon::init () SGPropertyNode *node = fgGetNode(branch.c_str(), num, true ); // Inputs - sound_pause = fgGetNode("/sim/sound/pause", false); + sound_working = fgGetNode("/sim/sound/working", true); lon_node = fgGetNode("/position/longitude-deg", true); lat_node = fgGetNode("/position/latitude-deg", true); alt_node = fgGetNode("/position/altitude-ft", true); @@ -176,7 +176,7 @@ FGMarkerBeacon::update(double dt) } if ( has_power() && serviceable->getBoolValue() - && !sound_pause->getBoolValue()) { + && sound_working->getBoolValue()) { // marker beacon blinking bool light_on = ( outer_blink || middle_blink || inner_blink ); diff --git a/src/Instrumentation/marker_beacon.hxx b/src/Instrumentation/marker_beacon.hxx index 3a98c11cd..25e435fea 100644 --- a/src/Instrumentation/marker_beacon.hxx +++ b/src/Instrumentation/marker_beacon.hxx @@ -55,7 +55,7 @@ class FGMarkerBeacon : public SGSubsystem SGPropertyNode_ptr audio_btn; SGPropertyNode_ptr audio_vol; SGPropertyNode_ptr serviceable; - SGPropertyNode_ptr sound_pause; + SGPropertyNode_ptr sound_working; bool need_update; diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index f18c5fb92..066f0262b 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -226,7 +226,7 @@ setFreeze (bool f) if ( smgr != NULL ) { if ( f ) { smgr->suspend(); - } else if (!fgGetBool("/sim/sound/pause")) { + } else if (fgGetBool("/sim/sound/working")) { smgr->resume(); } } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 896a38bfe..07d232a80 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -480,19 +480,19 @@ static void fgMainLoop( void ) { // Update the sound manager last so it can use the CPU while the GPU // is processing the scenery (doubled the frame-rate for me) -EMH- #ifdef ENABLE_AUDIO_SUPPORT - static SGPropertyNode *sound_pause = fgGetNode("/sim/sound/pause"); + static SGPropertyNode *sound_enabled = fgGetNode("/sim/sound/enabled"); static SGSoundMgr *smgr = globals->get_soundmgr(); - static bool smgr_suspend = false; - if (smgr_suspend != sound_pause->getBoolValue()) { - if (smgr_suspend == false) { // request to suspend + static bool smgr_enabled = true; + if (smgr_enabled != sound_enabled->getBoolValue()) { + if (smgr_enabled == true) { // request to suspend smgr->suspend(); } else { smgr->resume(); } - smgr_suspend = sound_pause->getBoolValue(); + smgr_enabled = sound_enabled->getBoolValue(); } - if (smgr_suspend == false) { + if (smgr_enabled == true) { static SGPropertyNode *volume = fgGetNode("/sim/sound/volume"); smgr->set_volume(volume->getFloatValue()); smgr->update(delta_time_sec); @@ -504,7 +504,7 @@ static void fgMainLoop( void ) { if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded() && cur_fdm_state->get_inited()) { fgSetBool("sim/sceneryloaded",true); - if (fgGetBool("/sim/sound/enabled")) { + if (fgGetBool("/sim/sound/working")) { smgr->activate(); } else { smgr->stop(); diff --git a/src/Main/options.cxx b/src/Main/options.cxx index b46424e53..ceca89101 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -189,7 +189,7 @@ fgSetDefaults () fgSetBool("/sim/hud/visibility", false); fgSetBool("/sim/panel/visibility", true); fgSetBool("/sim/sound/enabled", true); - fgSetBool("/sim/sound/pause", false); + fgSetBool("/sim/sound/working", true); // Flight Model options fgSetString("/sim/flight-model", "jsb"); @@ -1293,8 +1293,8 @@ struct OptionDesc { {"enable-hud", false, OPTION_BOOL, "/sim/hud/visibility", true, "", 0 }, {"disable-panel", false, OPTION_BOOL, "/sim/panel/visibility", false, "", 0 }, {"enable-panel", false, OPTION_BOOL, "/sim/panel/visibility", true, "", 0 }, - {"disable-sound", false, OPTION_BOOL, "/sim/sound/enabled", false, "", 0 }, - {"enable-sound", false, OPTION_BOOL, "/sim/sound/enabled", true, "", 0 }, + {"disable-sound", false, OPTION_BOOL, "/sim/sound/working", false, "", 0 }, + {"enable-sound", false, OPTION_BOOL, "/sim/sound/working", true, "", 0 }, {"sound-device", true, OPTION_STRING, "/sim/sound/device-name", false, "", 0 }, {"airport", true, OPTION_STRING, "/sim/presets/airport-id", false, "", 0 }, {"runway", true, OPTION_FUNC, "", false, "", fgOptRunway }, diff --git a/src/Sound/voice.cxx b/src/Sound/voice.cxx index 04e9a3deb..7ba8b2fb9 100644 --- a/src/Sound/voice.cxx +++ b/src/Sound/voice.cxx @@ -35,7 +35,7 @@ FGVoiceMgr::FGVoiceMgr() : _host(fgGetString(VOICE "/host", "localhost")), _port(fgGetString(VOICE "/port", "1314")), _enabled(fgGetBool(VOICE "/enabled", false)), - _pausedNode(fgGetNode("/sim/sound/pause", true)) + _pausedNode(fgGetNode("/sim/sound/working", true)) { #if defined(ENABLE_THREADS) if (!_enabled) @@ -83,7 +83,7 @@ void FGVoiceMgr::update(double) if (!_enabled) return; - _paused = _pausedNode->getBoolValue(); + _paused = !_pausedNode->getBoolValue(); for (unsigned int i = 0; i < _voices.size(); i++) { _voices[i]->update(); #if !defined(ENABLE_THREADS) From 86cd5252007c294616392c5a9d89a102953dcf64 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Mon, 30 Nov 2009 14:24:16 +0000 Subject: [PATCH 55/62] update to allow selection of a new sound device --- src/Main/main.cxx | 11 +++++++++++ src/Main/options.cxx | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 07d232a80..ca63accb2 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -104,6 +104,8 @@ long global_multi_loop; SGTimeStamp last_time_stamp; SGTimeStamp current_time_stamp; +void fgSetNewSoundDevice(const char *); + // The atexit() function handler should know when the graphical subsystem // is initialized. extern int _bootstrap_OSInit; @@ -509,6 +511,7 @@ static void fgMainLoop( void ) { } else { smgr->stop(); } + globals->get_props()->tie("/sim/sound/device", SGRawValueFunctions<const char *>(0, fgSetNewSoundDevice), false); } fgRequestRedraw(); @@ -516,6 +519,14 @@ static void fgMainLoop( void ) { SG_LOG( SG_ALL, SG_DEBUG, "" ); } +void fgSetNewSoundDevice(const char *device) +{ + globals->get_soundmgr()->suspend(); + globals->get_soundmgr()->stop(); + globals->get_soundmgr()->init(device); + globals->get_soundmgr()->resume(); +} + // Operation for querying OpenGL parameters. This must be done in a // valid OpenGL context, potentially in another thread. namespace diff --git a/src/Main/options.cxx b/src/Main/options.cxx index ceca89101..e03f1b1f0 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -204,7 +204,7 @@ fgSetDefaults () fgSetBool("/sim/rendering/shading", true); fgSetBool("/sim/rendering/skyblend", true); fgSetBool("/sim/rendering/textures", true); - fgTie( "/sim/rendering/filtering", SGGetTextureFilter, SGSetTextureFilter, false); + fgTie( "/sim/rendering/filtering", SGGetTextureFilter, SGSetTextureFilter, false); fgSetInt("/sim/rendering/filtering", 1); fgSetBool("/sim/rendering/wireframe", false); fgSetBool("/sim/rendering/horizon-effect", false); From e657a53b329259e5fe6d8b577767a18db2456d62 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 1 Dec 2009 10:37:49 +0000 Subject: [PATCH 56/62] Turned out a tied proeprty can't be used as a user archive, use a different one --- src/Main/main.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index ca63accb2..330ef0a5a 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -511,7 +511,8 @@ static void fgMainLoop( void ) { } else { smgr->stop(); } - globals->get_props()->tie("/sim/sound/device", SGRawValueFunctions<const char *>(0, fgSetNewSoundDevice), false); + globals->get_props()->tie("/sim/sound/devices/name", + SGRawValueFunctions<const char *>(0, fgSetNewSoundDevice), false); } fgRequestRedraw(); From c7ef67df800c8f5a57a1fe61b24e66f934774449 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Wed, 2 Dec 2009 09:34:06 +0000 Subject: [PATCH 57/62] add avionics enable/disable and volume control to the sound fx class. --- src/Main/fg_commands.cxx | 2 +- src/Sound/fg_fx.cxx | 34 ++++++++++++++-------------------- src/Sound/fg_fx.hxx | 5 ++--- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 151efa207..f998b5d6c 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -1260,7 +1260,7 @@ do_play_audio_sample (const SGPropertyNode * arg) static FGSampleQueue *queue = 0; if ( !queue ) { SGSoundMgr *smgr = globals->get_soundmgr(); - queue = new FGSampleQueue(smgr, "queue"); + queue = new FGSampleQueue(smgr, "chatter"); queue->tie_to_listener(); } diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 831375454..739b746f0 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -39,18 +39,16 @@ #include <simgear/sound/xmlsound.hxx> FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : - last_enabled( true ), - last_volume( 0.0 ), _enabled( fgGetNode("/sim/sound/effects/enabled", true) ), - _volume( fgGetNode("/sim/sound/effects/volume", true) ) + _volume( fgGetNode("/sim/sound/effects/volume", true) ), + _avionics_enabled( fgGetNode("/sim/sound/avionics/enabled", true) ), + _avionics_volume( fgGetNode("/sim/sound/avionics/volume", true) ) { SGSampleGroup::_smgr = smgr; SGSampleGroup::_refname = refname; SGSampleGroup::_smgr->add(this, refname); _avionics = _smgr->find("avionics", true); _avionics->tie_to_listener(); - _enabled->setBoolValue(true); - _volume->setFloatValue(1.0); } @@ -118,22 +116,16 @@ FGFX::reinit() void FGFX::update (double dt) { - bool new_enabled = _enabled->getBoolValue(); - if ( new_enabled != last_enabled ) { - if ( new_enabled ) { - resume(); - } else { - suspend(); - } - last_enabled = new_enabled; - } + if ( _avionics_enabled->getBoolValue() ) + _avionics->resume(); // no-op if already in resumed state + else + _avionics->suspend(); + _avionics->set_volume( _avionics_volume->getDoubleValue() ); - if ( new_enabled ) { - double volume = _volume->getDoubleValue(); - if ( volume != last_volume ) { - set_volume( volume ); - last_volume = volume; - } + + if ( _enabled->getBoolValue() ) { + set_volume( _volume->getDoubleValue() ); + resume(); // update sound effects if not paused for ( unsigned int i = 0; i < _sound.size(); i++ ) { @@ -142,6 +134,8 @@ FGFX::update (double dt) SGSampleGroup::update(dt); } + else + suspend(); } // end of fg_fx.cxx diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index f28d3677b..caa32646a 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -60,11 +60,10 @@ private: SGSharedPtr<SGSampleGroup> _avionics; std::vector<SGXmlSound *> _sound; - bool last_enabled; - double last_volume; - SGPropertyNode_ptr _enabled; SGPropertyNode_ptr _volume; + SGPropertyNode_ptr _avionics_enabled; + SGPropertyNode_ptr _avionics_volume; }; From 6324d5a03d3558c69cbbfffff5b4bceecb4323a0 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore@redhat.com> Date: Mon, 7 Dec 2009 06:59:04 +0100 Subject: [PATCH 58/62] Change int to unsigned in sound device traversal --- src/Main/fg_init.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 6e99a68bc..f2784e234 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1457,7 +1457,7 @@ bool fgInitSubsystems() { vector <const char*>devices = globals->get_soundmgr()->get_available_devices(); - for (int i=0; i<devices.size(); i++) { + for (unsigned int i=0; i<devices.size(); i++) { SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true); p->setStringValue(devices[i]); } From 0dc35c8d38c8d59ab69362299e76610c3b1ca045 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 8 Dec 2009 09:48:00 +0000 Subject: [PATCH 59/62] John Denker: Suggestion: It might be helpful to promote each of the .c files to .cxx. Rationale: -- The configure/makefile system handles CFLAGS differently from CXXFLAGS. -- It is important for the *info programs to compiled and run in exactly the same environment as the main fgfs program. Some users depend on compiler or linker flags such as rpath that strongly affect the results of the *info programs. -- There is no downside; you code compiles just fine as-is under the c++ compiler. second part of the original commit, for ehofman/sound --- tests/Makefile.am | 2 +- tests/{alcinfo.c => alcinfo.cxx} | 33 ++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 15 deletions(-) rename tests/{alcinfo.c => alcinfo.cxx} (91%) diff --git a/tests/Makefile.am b/tests/Makefile.am index 57a0bd77c..87d87c7ec 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,7 @@ est_epsilon_LDADD = $(opengl_LIBS) gl_info_SOURCES = gl-info.c gl_info_LDADD = $(opengl_LIBS) -alcinfo_SOURCES = alcinfo.c +alcinfo_SOURCES = alcinfo.cxx alcinfo_LDADD = $(openal_LIBS) test_env_map_SOURCES = test-env-map.cxx diff --git a/tests/alcinfo.c b/tests/alcinfo.cxx similarity index 91% rename from tests/alcinfo.c rename to tests/alcinfo.cxx index acc40a22d..2f569390d 100644 --- a/tests/alcinfo.c +++ b/tests/alcinfo.cxx @@ -36,6 +36,9 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <string> + +using std::string; #ifndef ALC_ALL_DEVICES_SPECIFIER # define ALC_ALL_DEVICES_SPECIFIER 0x1013 @@ -48,7 +51,7 @@ static const int maxmimumWidth = 79; void printExtensions (const char *, char, const char *); void displayDevices(const char *, const char *); char *getDeviceName(int, char **); -void testForError(void *, char *); +void testForError(void *, const string&); void testForALCError(ALCdevice *); int main(int argc, char **argv) @@ -96,21 +99,23 @@ int main(int argc, char **argv) alcGetIntegerv(device, ALC_FREQUENCY, 1, data); printf("mixer frequency: %u hz\n", data[0]); - testForError(device, "invalid context"); + testForALCError(device); alcGetIntegerv(device, ALC_REFRESH, 1, data+1); printf("refresh rate : %u hz\n", data[0]/data[1]); - testForError(device, "invalid context"); + testForALCError(device); data[0] = 0; alcGetIntegerv(device, ALC_MONO_SOURCES, 1, data); - printf("supported sources; mono: %u, ", data[0]); - testForError(device, "invalid context"); + error = alcGetError(device); + if (error == AL_NONE) { + printf("supported sources; mono: %u, ", data[0]); - data[0] = 0; - alcGetIntegerv(device, ALC_STEREO_SOURCES, 1, data); - printf("stereo: %u\n", data[0]); - testForError(device, "invalid context"); + data[0] = 0; + alcGetIntegerv(device, ALC_STEREO_SOURCES, 1, data); + printf("stereo: %u\n", data[0]); + testForALCError(device); + } printf("ALC version: "); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, data); @@ -248,15 +253,15 @@ printExtensions (const char *header, char separator, const char *extensions) } char * -getCommandLineOption(int argc, char **argv, char *option) +getCommandLineOption(int argc, char **argv, const string& option) { - int slen = strlen(option); + int slen = option.size(); char *rv = 0; int i; for (i=0; i<argc; i++) { - if (strncmp(argv[i], option, slen) == 0) + if (strncmp(argv[i], option.c_str(), slen) == 0) { i++; if (i<argc) rv = argv[i]; @@ -317,11 +322,11 @@ displayDevices(const char *type, const char *list) } void -testForError(void *p, char *s) +testForError(void *p, const string& s) { if (p == NULL) { - printf("\nError: %s\n\n", s); + printf("\nError: %s\n\n", s.c_str()); exit(-1); } } From 168dc6ff922f5f6d29966fac126afdaa1086422d Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 8 Dec 2009 09:53:29 +0000 Subject: [PATCH 60/62] if volume is too low, skip the function entirely --- src/ATCDCL/ATC.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index b4a17ae97..6bb6a2282 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -222,6 +222,8 @@ void FGATC::SetData(ATCData* d) { // The repeating flag indicates whether the message should be repeated continuously or played once. void FGATC::Render(string& msg, const float volume, const string& refname, const bool repeating) { + if (volume < 0.05) return; + if (repeating) fgSetString("/sim/messages/atis", msg.c_str()); else @@ -232,7 +234,7 @@ void FGATC::Render(string& msg, const float volume, if(_voice) { size_t len; void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len); - if(buf && (volume > 0.05)) { + if(buf) { NoRender(refname); try { // >>> Beware: must pass a (new) object to the (add) method, From 641f0008602dd699ad17c9e12c331ced7392e1d1 Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Tue, 8 Dec 2009 14:43:29 +0000 Subject: [PATCH 61/62] Activate external-view checkbox for avionics --- src/Sound/fg_fx.cxx | 12 ++++++++---- src/Sound/fg_fx.hxx | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 739b746f0..f1c11f775 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -42,7 +42,9 @@ FGFX::FGFX ( SGSoundMgr *smgr, const string &refname ) : _enabled( fgGetNode("/sim/sound/effects/enabled", true) ), _volume( fgGetNode("/sim/sound/effects/volume", true) ), _avionics_enabled( fgGetNode("/sim/sound/avionics/enabled", true) ), - _avionics_volume( fgGetNode("/sim/sound/avionics/volume", true) ) + _avionics_volume( fgGetNode("/sim/sound/avionics/volume", true) ), + _avionics_external( fgGetNode("/sim/sound/avionics/external-view", true) ), + _internal( fgGetNode("/sim/current-view/internal", true) ) { SGSampleGroup::_smgr = smgr; SGSampleGroup::_refname = refname; @@ -116,12 +118,14 @@ FGFX::reinit() void FGFX::update (double dt) { - if ( _avionics_enabled->getBoolValue() ) + bool active = _avionics_external->getBoolValue() || + _internal->getBoolValue(); + + if ( active && _avionics_enabled->getBoolValue() ) _avionics->resume(); // no-op if already in resumed state else _avionics->suspend(); - _avionics->set_volume( _avionics_volume->getDoubleValue() ); - + _avionics->set_volume( _avionics_volume->getFloatValue() ); if ( _enabled->getBoolValue() ) { set_volume( _volume->getDoubleValue() ); diff --git a/src/Sound/fg_fx.hxx b/src/Sound/fg_fx.hxx index caa32646a..26c802f34 100644 --- a/src/Sound/fg_fx.hxx +++ b/src/Sound/fg_fx.hxx @@ -64,6 +64,8 @@ private: SGPropertyNode_ptr _volume; SGPropertyNode_ptr _avionics_enabled; SGPropertyNode_ptr _avionics_volume; + SGPropertyNode_ptr _avionics_external; + SGPropertyNode_ptr _internal; }; From 61ffbf4615c4ad51d1cdd4cfe35ff28bc00e90fc Mon Sep 17 00:00:00 2001 From: ehofman <ehofman> Date: Thu, 10 Dec 2009 09:56:42 +0000 Subject: [PATCH 62/62] activate atc settings in the sound mixer dialog --- src/ATCDCL/ATC.cxx | 23 ++++++++++++++++++++--- src/ATCDCL/ATC.hxx | 6 ++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/ATCDCL/ATC.cxx b/src/ATCDCL/ATC.cxx index 6bb6a2282..41c56e648 100644 --- a/src/ATCDCL/ATC.cxx +++ b/src/ATCDCL/ATC.cxx @@ -36,7 +36,7 @@ FGATC::FGATC() : _voiceOK(false), - _playing(false), + _playing(false), _sgr(NULL), freqClear(true), receiving(false), @@ -59,6 +59,11 @@ FGATC::FGATC() : { SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("atc", true); + + _volume = fgGetNode("/sim/sound/atc/volume", true); + _enabled = fgGetNode("/sim/sound/atc/enabled", true); + _atc_external = fgGetNode("/sim/sound/atc/external-view", true); + _internal = fgGetNode("/sim/current-view/internal", true); } FGATC::~FGATC() { @@ -107,6 +112,18 @@ void FGATC::Update(double dt) { } } +#ifdef ENABLE_AUDIO_SUPPORT + bool active = _atc_external->getBoolValue() || + _internal->getBoolValue(); + + if ( active && _enabled->getBoolValue() ) { + _sgr->set_volume( _volume->getFloatValue() ); + _sgr->resume(); // no-op if already in resumed state + } else { + _sgr->suspend(); + } +#endif + if(_transmit) { _counter = 0.0; _max_count = 5.0; // FIXME - hardwired length of message - need to calculate it! @@ -232,7 +249,7 @@ void FGATC::Render(string& msg, const float volume, #ifdef ENABLE_AUDIO_SUPPORT _voice = (_voiceOK && fgGetBool("/sim/sound/voice")); if(_voice) { - size_t len; + size_t len; void* buf = _vPtr->WriteMessage((char*)msg.c_str(), &len); if(buf) { NoRender(refname); @@ -325,7 +342,7 @@ std::istream& operator >> ( std::istream& fin, ATCData& a ) } double lat, lon, elev; - + fin >> lat >> lon >> elev >> f >> a.range >> a.ident; a.geod = SGGeod::fromDegM(lon, lat, elev); a.name = ""; diff --git a/src/ATCDCL/ATC.hxx b/src/ATCDCL/ATC.hxx index dd3fc8be2..e2751460e 100644 --- a/src/ATCDCL/ATC.hxx +++ b/src/ATCDCL/ATC.hxx @@ -24,6 +24,7 @@ #include <simgear/constants.h> #include <simgear/compiler.h> +#include <simgear/props/props.hxx> #include <simgear/misc/sgstream.hxx> #include <simgear/math/sg_geodesy.hxx> #include <simgear/debug/logstream.hxx> @@ -247,6 +248,11 @@ private: bool _transmitting; // we are transmitting double _counter; double _max_count; + + SGPropertyNode_ptr _volume; + SGPropertyNode_ptr _enabled; + SGPropertyNode_ptr _atc_external; + SGPropertyNode_ptr _internal; }; std::istream& operator>> ( std::istream& fin, ATCData& a );