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 );