diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/audioengine.cpp ./indra/llaudio/audioengine.cpp
--- ./indra/llaudio/audioengine.cpp	2007-12-21 22:03:17.000000000 +0000
+++ ./indra/llaudio/audioengine.cpp	2008-01-09 19:38:22.000000000 +0000
@@ -1323,7 +1325,7 @@
 BOOL LLAudioSource::isDone()
 {
 	const F32 MAX_AGE = 60.f;
-	const F32 MAX_UNPLAYED_AGE = 15.f;
+	const F32 MAX_UNPLAYED_AGE = 30.f;
 	if (isLoop())
 	{
 		// Looped sources never die on their own.
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/audioengine_dummy.cpp ./indra/llaudio/audioengine_dummy.cpp
--- ./indra/llaudio/audioengine_dummy.cpp	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/audioengine_dummy.cpp	2008-01-06 21:41:07.000000000 +0000
@@ -0,0 +1,79 @@
+#include "linden_common.h"
+
+#include "audioengine_dummy.h"
+#include "listener_dummy.h"
+
+LLAudioEngine_DUMMY::LLAudioEngine_DUMMY(){
+}
+
+LLAudioEngine_DUMMY::~LLAudioEngine_DUMMY(){
+}
+
+BOOL LLAudioEngine_DUMMY::init(const S32 num_channels, void* userdata){
+	LLAudioEngine::init(num_channels, userdata);
+
+	llinfos << "LLAudioEngine_DUMMY::init() initializing" << llendl;
+
+	return TRUE;
+}
+
+void LLAudioEngine_DUMMY::idle(F32 max_decode_time){
+	LLAudioEngine::idle(max_decode_time);
+}
+
+void LLAudioEngine_DUMMY::allocateListener(){
+	mListenerp = (LLListener *) new LLListener_DUMMY();
+	if(!mListenerp){
+		llwarns << "LLAudioEngine_DUMMY::allocateListener() Listener creation failed" << llendl;
+	}
+}
+
+void LLAudioEngine_DUMMY::shutdown(){
+	LLAudioEngine::shutdown();
+
+	llinfos << "LLAudioEngine_DUMMY::shutdown()" << llendl;
+
+	delete mListenerp;
+	mListenerp = NULL;
+}
+
+LLAudioBuffer *LLAudioEngine_DUMMY::createBuffer(){
+   return new LLAudioBufferDUMMY();
+}
+
+LLAudioChannel *LLAudioEngine_DUMMY::createChannel(){
+   return new LLAudioChannelDUMMY();
+}
+
+void LLAudioEngine_DUMMY::setInternalGain(F32 gain){
+	//llinfos << "LLAudioEngine_DUMMY::setInternalGain() Gain: " << gain << llendl;
+}
+
+void LLAudioEngine_DUMMY::startInternetStream(const char* url){
+	if (url) {
+		llinfos << "LLAudioEngine_DUMMY::startInternetStream() Starting internet stream: " << url << llendl;
+	}else{
+		llinfos << "LLAudioEngine_DUMMY::startInternetStream() Set internet stream to null" << llendl;
+	}
+}
+
+LLAudioChannelDUMMY::LLAudioChannelDUMMY(){
+}
+
+LLAudioChannelDUMMY::~LLAudioChannelDUMMY(){
+}
+
+LLAudioBufferDUMMY::LLAudioBufferDUMMY(){
+}
+
+LLAudioBufferDUMMY::~LLAudioBufferDUMMY(){
+}
+
+BOOL LLAudioBufferDUMMY::loadWAV(const char *filename){
+	llinfos << "LLAudioBufferDUMMY::loadWAV() : " << filename << llendl;
+	return FALSE;
+}
+
+U32 LLAudioBufferDUMMY::getLength(){
+	return 0;
+}
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/audioengine_dummy.h ./indra/llaudio/audioengine_dummy.h
--- ./indra/llaudio/audioengine_dummy.h	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/audioengine_dummy.h	2008-01-06 21:41:07.000000000 +0000
@@ -0,0 +1,61 @@
+#ifndef LL_AUDIOENGINE_DUMMY_H
+#define LL_AUDIOENGINE_DUMMY_H
+
+#include "audioengine.h"
+
+#include "listener_dummy.h"
+
+class LLAudioEngine_DUMMY : public LLAudioEngine 
+{
+public:
+	LLAudioEngine_DUMMY();
+	virtual ~LLAudioEngine_DUMMY();
+
+	virtual BOOL init(const S32 num_channels, void *user_data);
+	virtual void allocateListener();
+
+	virtual void shutdown();
+
+	virtual void idle(F32 max_decode_time = 0.f);
+
+	void setInternalGain(F32 gain);
+
+	LLAudioBuffer* createBuffer();
+	LLAudioChannel* createChannel();
+
+	// Internet stream methods
+	virtual void startInternetStream(const char* url);
+	void stopInternetStream(){};
+	void pauseInternetStream(int){};
+	int isInternetStreamPlaying(){};
+
+	void updateWind(LLVector3, F32){};
+	void initWind(){};
+	void cleanupWind(){};
+};
+
+class LLAudioChannelDUMMY : public LLAudioChannel{
+	public:
+		LLAudioChannelDUMMY();
+		virtual ~LLAudioChannelDUMMY();
+	protected:
+		void play(){};
+		void playSynced(LLAudioChannel *channelp){};
+		void cleanup(){};
+		BOOL isPlaying(){};
+
+		BOOL updateBuffer(){};
+		void update3DPosition(){};
+		void updateLoop(){};
+};
+
+class LLAudioBufferDUMMY : public LLAudioBuffer{
+	public:
+		LLAudioBufferDUMMY();
+		virtual ~LLAudioBufferDUMMY();
+
+		BOOL loadWAV(const char *filename);
+		U32 getLength();
+};
+
+#endif
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/audioengine_openal.cpp ./indra/llaudio/audioengine_openal.cpp
--- ./indra/llaudio/audioengine_openal.cpp	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/audioengine_openal.cpp	2008-01-09 23:00:56.000000000 +0000
@@ -0,0 +1,605 @@
+
+// OpenAL patch by Seg Baphomet
+// Additonal work by Michelle2 Zenovka
+
+/* ***** TODO *********
+* Wind noise is not currently implemented
+*/
+
+
+
+#include "linden_common.h"
+#include "llmath.h"
+#include "llrand.h"
+#include "audioengine_openal.h"
+#include "listener_openal.h"
+
+#define ARRAY_LEN(a) (sizeof (a) / sizeof((a)[0])) 
+
+
+#if LL_OPENAL
+
+// These globals for the wind filter.  Blech!
+F64 gbuf0 = 0.0;
+F64 gbuf1 = 0.0;
+F64 gbuf2 = 0.0;
+F64 gbuf3 = 0.0;
+F64 gbuf4 = 0.0;
+F64 gbuf5 = 0.0;
+F64 gY0 = 0.0;
+F64 gY1 = 0.0;
+
+F32 gTargetGain = 0.f;
+F32 gCurrentGain = 0.f;
+F32 gTargetFreq = 100.f;
+F32 gCurrentFreq = 100.f;
+F32 gTargetPanGainR = 0.5f;
+F32 gCurrentPanGainR = 0.5f;
+
+
+
+
+// Safe strcpy
+#if LL_WINDOWS || LL_LINUX
+static size_t strlcpy( char* dest, const char* src, size_t dst_size )
+{
+	size_t source_len = 0;
+	size_t min_len = 0;
+	if( dst_size > 0 )
+	{
+		if( src )
+		{
+			source_len = strlen(src);	/*Flawfinder: ignore*/
+			min_len = llmin( dst_size - 1, source_len );
+			memcpy(dest, src, min_len);	/*Flawfinder: ignore*/	
+		}
+		dest[min_len] = '\0';
+	}
+	return source_len;
+}
+#else
+// apple ships with the non-standard strlcpy in /usr/include/string.h:
+// size_t strlcpy(char *, const char *, size_t);
+#endif
+
+
+
+LLAudioEngine_OpenAL::LLAudioEngine_OpenAL(){
+
+	//Oh what a friend we have in gstreamer
+	// Create an instance of the gstreamer class for firing audio streams at
+	// if WE do this we can control the pointer and video can do what it wants
+	// withs its own version.	
+	m_streamer=new LLMediaImplGStreamer ();
+
+	if(!m_streamer)
+	{
+		llwarns << "LLAudioEngine_OpenAL:: Failed to create our private gstreamer audio instance" << llendl;
+	}
+	
+	if(m_streamer)
+	{
+		//Good time to kick gstreamer?
+		llinfos << "LLAudioEngine_OpenAL:: Initalisating audio streamer" <<llendl;	
+		m_streamer->init (); 
+	}
+	
+
+}
+
+LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL(){
+}
+
+BOOL LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata){
+	LLAudioEngine::init(num_channels, userdata);
+
+
+	if (NULL != getenv("LL_BAD_OPENAL")) /*Flawfinder: ignore*/
+	{
+		llwarns << "LLAudioEngine_OpenAL::init() Not stating openAL due to LL_BAD_OPENAL environmental variable set "<< llendl;
+		return FALSE;
+	}
+
+	if(!alutInit(NULL, NULL)){
+		llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
+		return FALSE;
+	}
+
+	initInternetStream();
+
+	llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
+
+	llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl;
+
+	return TRUE;
+}
+
+void LLAudioEngine_OpenAL::idle(F32 max_decode_time){
+	LLAudioEngine::idle(max_decode_time);
+}
+
+void LLAudioEngine_OpenAL::allocateListener(){
+	mListenerp = (LLListener *) new LLListener_OpenAL();
+	if(!mListenerp){
+		llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl;
+	}
+}
+
+void LLAudioEngine_OpenAL::shutdown(){
+	LLAudioEngine::shutdown();
+
+	if(!alutExit()){
+		llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
+	}
+
+	llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
+
+	delete mListenerp;
+	mListenerp = NULL;
+}
+
+LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer(){
+   return new LLAudioBufferOpenAL();
+}
+
+LLAudioChannel *LLAudioEngine_OpenAL::createChannel(){
+   return new LLAudioChannelOpenAL();
+}
+
+void LLAudioEngine_OpenAL::setInternalGain(F32 gain){
+	//llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl;
+	alListenerf(AL_GAIN, gain);
+}
+
+LLAudioChannelOpenAL::LLAudioChannelOpenAL(){
+	alGenSources(1, &ALSource);
+}
+
+LLAudioChannelOpenAL::~LLAudioChannelOpenAL(){
+	cleanup();
+	alDeleteSources(1, &ALSource);
+}
+
+void LLAudioChannelOpenAL::cleanup(){
+	alSourceStop(ALSource);
+	mCurrentBufferp = NULL;
+}
+
+void LLAudioChannelOpenAL::play(){
+	if(!isPlaying()){
+		alSourcePlay(ALSource);
+		getSource()->setPlayedOnce(TRUE);
+	}
+}
+
+void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp){
+	play();
+}
+
+BOOL LLAudioChannelOpenAL::isPlaying(){
+	ALint state;
+	alGetSourcei(ALSource, AL_SOURCE_STATE, &state);
+	if(state == AL_PLAYING){
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL LLAudioChannelOpenAL::updateBuffer(){
+	if (LLAudioChannel::updateBuffer()){
+		// Base class update returned TRUE, which means that we need to actually
+		// set up the source for a different buffer.
+		LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
+		alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer());
+		alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
+		alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
+	}
+
+	return TRUE;
+}
+
+void LLAudioChannelOpenAL::update3DPosition(){
+	if(!mCurrentSourcep){
+		return;
+	}
+	if (mCurrentSourcep->isAmbient()){
+		alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0);
+		alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
+		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
+		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0);
+		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE);
+	}else{
+		LLVector3 float_pos;
+		float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+		alSourcefv(ALSource, AL_POSITION, float_pos.mV);
+		//llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl;
+		alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
+		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
+		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0);
+		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE);
+	}
+	//llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl;
+	alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
+}
+
+LLAudioBufferOpenAL::LLAudioBufferOpenAL(){
+	ALBuffer = AL_NONE;
+}
+
+LLAudioBufferOpenAL::~LLAudioBufferOpenAL(){
+	cleanup();
+}
+
+void LLAudioBufferOpenAL::cleanup(){
+	if(ALBuffer != AL_NONE){
+		alDeleteBuffers(1, &ALBuffer);
+	}
+}
+
+BOOL LLAudioBufferOpenAL::loadWAV(const char *filename){
+	cleanup();
+	ALBuffer = alutCreateBufferFromFile(filename);
+	if(ALBuffer == AL_NONE){
+		//ALenum error = alutGetError();
+		//llwarns << "LLAudioBufferOpenAL::loadWAV() Error loading " << filename
+		//	<< " " << alutGetErrorString(error) << llendl;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+U32 LLAudioBufferOpenAL::getLength(){
+	if(ALBuffer == AL_NONE){
+		return 0;
+	}
+	ALint length;
+	alGetBufferi(ALBuffer, AL_SIZE, &length);
+	return length >> 2;
+}
+
+// ------------
+
+void LLAudioEngine_OpenAL::initInternetStream(){
+	mInternetStreamURL[0] = 0;
+	
+}
+
+void LLAudioEngine_OpenAL::startInternetStream(const char* url){
+
+	if(!m_streamer)
+		return;
+
+	if (url) {
+		llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl;
+		strlcpy(mInternetStreamURL, url, ARRAY_LEN(url));		
+		m_streamer->load ( url );
+		llinfos << "LLAudioEngine_OpenAL::startInternetStream() Playing....." << llendl;		
+		m_streamer->play ();
+
+	}else{
+		llinfos << "LLAudioEngine_OpenAL::startInternetStream() seting stream to NULL"<< llendl;
+		mInternetStreamURL[0] = 0;
+		m_streamer->stop ();
+	}
+}
+
+void LLAudioEngine_OpenAL::updateInternetStream(){
+}
+
+void LLAudioEngine_OpenAL::stopInternetStream(){
+	
+	if(!m_streamer)
+		return;
+
+	mInternetStreamURL[0] = 0;
+	m_streamer->stop ();
+}
+
+void LLAudioEngine_OpenAL::pauseInternetStream(int pause){
+
+	if(!m_streamer)
+		return;
+	
+	if(pause)
+		m_streamer->pause();
+	else
+		m_streamer->play();
+
+}
+
+int LLAudioEngine_OpenAL::isInternetStreamPlaying(){
+
+	if(!m_streamer)
+		return 0;
+	
+	if(m_streamer->isPlaying())
+	{
+		return 1; // Active and playing
+	}	
+	if(m_streamer->isPaused())
+	{
+		return 2; // paused
+	}
+
+	return 0; // Stopped
+}
+
+void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out){
+}
+
+void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol){
+	// Set the gstreamer volume here
+	if(!m_streamer)
+		return;
+
+	vol = llclamp(vol, 0.f, 1.f);
+	m_streamer->setVolume(vol);
+}
+
+const char* LLAudioEngine_OpenAL::getInternetStreamURL(){
+	return mInternetStreamURL;
+}
+
+#define NO_WIND_BUFFERS 5
+static ALuint wind_buffers[NO_WIND_BUFFERS];
+static ALuint wind_sources[1];
+static S16 *winddata=NULL;
+
+void LLAudioEngine_OpenAL::initWind()
+{
+
+//	if (!mEnableWind)
+//	{
+//		return;
+//	}
+
+	ALenum error;
+	
+	llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
+
+	alGetError(); /* clear error */
+	alGenBuffers(NO_WIND_BUFFERS,wind_buffers);
+	if((error=alGetError()) != AL_NO_ERROR)
+	{
+		llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffers: "<<error<<llendl; 
+	}
+	
+	alGenSources(1,wind_sources);
+
+	if((error=alGetError()) != AL_NO_ERROR)
+	{
+		llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl; 
+	}
+
+	//winddata=(S16*)malloc(sizeof(S16)*44100*0.2); //20ms of data
+	winddata=(S16*)malloc(sizeof(S16)*44100); //20ms of data //loose the 0.2 to give a huge padded buffer for the moment, i think we need a x2 in there fo stereo though, i think its sizeof(S16)*44100*2*0.2
+
+
+	llinfos << "LLAudioEngine_OpenAL::initWind() end" << llendl;
+
+}
+
+void LLAudioEngine_OpenAL::cleanupWind()
+{
+
+//	if (!mEnableWind)
+//	{
+//		return;
+//	}
+
+	alDeleteBuffers(5,wind_buffers);
+
+	alDeleteSources(1, wind_sources);
+
+
+	if(winddata)
+		free(winddata);
+
+}
+
+static BOOL first_wind=TRUE;
+
+ALfloat source0Pos[]={ -2.0, 0.0, 0.0};
+ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
+
+void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
+{
+	LLVector3 wind_pos;
+	F64 pitch;
+	F64 center_freq;
+	ALenum error;
+
+	mMaxWindGain=1.0;
+
+//	if (!mEnableWind)
+//	{
+//		return;
+//	}
+
+	if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+	{
+	
+		// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+		// need to convert this to the conventional orientation DS3D and OpenAL use
+		// where +X = right, +Y = up, +Z = backwards
+
+		wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+		// cerr << "Wind update" << endl;
+
+		pitch = 1.0 + mapWindVecToPitch(wind_vec);
+		center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+		
+		gTargetFreq = (F32)center_freq;
+		gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+		gTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+  	
+		alSourcef(wind_sources[0], AL_GAIN, gTargetGain);
+		alSourcef(wind_sources[0], AL_PITCH, pitch);
+    		alSourcefv(wind_sources[0], AL_POSITION, source0Pos);
+    		alSourcefv(wind_sources[0], AL_VELOCITY, source0Vel);
+    		alSourcei(wind_sources[0], AL_LOOPING, AL_FALSE);
+
+	}
+
+	// ok lets make a wind buffer now
+
+	if(first_wind==TRUE)
+	{
+		llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer" << llendl;
+		alGetError(); /* clear error */
+		
+		for(int counter=0;counter<5;counter++)
+		{
+			alBufferData(wind_buffers[counter],AL_FORMAT_STEREO16,windDSP((void*)winddata,2*44100*0.2),2*44100*0.2*sizeof(U16),44100);
+			if((error=alGetError()) != AL_NO_ERROR)
+			{
+				llwarns << "LLAudioEngine_OpenAL::initWind() Error creating INITAL WIND BUFFER 1: "<<error<<llendl; 
+			}
+		}
+
+		
+		alSourcePlay(wind_sources[0]);
+		if((error=alGetError()) != AL_NO_ERROR)
+		{
+			llwarns << "LLAudioEngine_OpenAL::initWind() Error inital wind play: "<<error<<llendl; 
+		}
+
+		first_wind=FALSE;	
+		llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer DONE!" << llendl;
+
+	}
+	else
+	{
+		int processed;
+ 		alGetSourcei(wind_sources[0], AL_BUFFERS_PROCESSED, &processed);
+		
+		while(processed--)
+    		{
+        		ALuint buffer;
+			int error; 
+			alSourceUnqueueBuffers(wind_sources[0], 1, &buffer);		
+			error = alGetError();
+ 			if(error != AL_NO_ERROR)
+  				llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
+
+			alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)winddata,44100*0.2),2*44100*0.2*sizeof(U16),44100);
+			error = alGetError();
+ 			if(error != AL_NO_ERROR)
+  				llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;		
+
+			alSourceQueueBuffers(wind_sources[0], 1, &buffer);
+			error = alGetError();
+ 			if(error != AL_NO_ERROR)
+  				llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;		
+
+		}
+	
+	}
+
+}
+
+
+/* This determines the format of the mixbuffer being passed in. change if you want to support int32 or float32 */
+#if LL_DARWIN
+	#define MIXBUFFERFORMAT S32
+#else
+	#define MIXBUFFERFORMAT S16
+#endif
+
+inline MIXBUFFERFORMAT clipSample(MIXBUFFERFORMAT sample, MIXBUFFERFORMAT min, MIXBUFFERFORMAT max)
+{
+	if (sample > max)
+		sample = max;
+	else if (sample < min)
+		sample = min;
+	
+	return sample;
+}
+
+void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length)
+{
+// originalbuffer = fsounds original mixbuffer.
+// newbuffer = the buffer passed from the previous DSP unit.
+// length = length in samples at this mix time.
+// param = user parameter passed through in FSOUND_DSP_Create.
+//
+// modify the buffer in some fashion
+
+	U8 *cursamplep = (U8*)newbuffer;
+	U8   wordsize = 2;
+
+#if LL_DARWIN
+	wordsize = sizeof(MIXBUFFERFORMAT);
+#else
+    //int		mixertype = FSOUND_GetMixer();
+    //if (mixertype == FSOUND_MIXER_BLENDMODE || mixertype == FSOUND_MIXER_QUALITY_FPU)
+ //   {
+//		wordsize = 4;
+  //  }
+#endif
+
+    double bandwidth = 50;
+    double inputSamplingRate = 44100;
+    double a0,b1,b2;
+ 
+    gTargetGain=1.0;
+    gCurrentPanGainR=0.5;
+    gCurrentGain=1.0;
+
+	llinfos << "LLAudioEngine_OpenAL:: making wind, length is " <<length<< " cur freq: "<<gCurrentFreq<<" t freq: "<<gTargetFreq<<" current gain: "<<gCurrentGain<<" T gain: "<<gTargetGain<< llendl;
+
+
+	// calculate resonant filter coeffs
+    	b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
+
+	while (length--)
+	{
+		gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
+		gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
+		gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
+		b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
+	    a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
+		double nextSample;
+
+	    // start with white noise
+		nextSample = ll_frand(2.0f) - 1.0f;
+									 
+#if 1 // LLAE_WIND_PINK apply pinking filter
+		gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample; 
+        gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
+        gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
+        gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
+        gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
+        gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
+			  
+        nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
+#endif
+			
+#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
+        nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
+
+        gY1 = gY0;
+        gY0 = nextSample;
+#endif
+
+	    nextSample *= gCurrentGain;
+		
+		MIXBUFFERFORMAT	sample;
+
+		sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
+		*(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
+		cursamplep += wordsize;
+
+		sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
+		*(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
+		cursamplep += wordsize;
+	}
+
+	return newbuffer;
+}
+
+
+
+#endif //LL_OPENAL
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/audioengine_openal.h ./indra/llaudio/audioengine_openal.h
--- ./indra/llaudio/audioengine_openal.h	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/audioengine_openal.h	2008-01-09 14:56:28.000000000 +0000
@@ -0,0 +1,85 @@
+#ifndef LL_AUDIOENGINE_OpenAL_H
+#define LL_AUDIOENGINE_OpenAL_H
+
+#define MAX_SIZE_STREAM_URL 1024
+
+#include "audioengine.h"
+
+#include "listener_openal.h"
+#include "llmediaimplgstreamer.h"
+
+class LLAudioEngine_OpenAL : public LLAudioEngine{
+	public:
+		LLAudioEngine_OpenAL();
+		virtual ~LLAudioEngine_OpenAL();
+
+		virtual BOOL init(const S32 num_channels, void *user_data);
+		virtual void allocateListener();
+
+		virtual void shutdown();
+
+		virtual void idle(F32 max_decode_time = 0.f);
+
+		void setInternalGain(F32 gain);
+
+		LLAudioBuffer* createBuffer();
+		LLAudioChannel* createChannel();
+
+		// Internet stream methods
+		virtual void initInternetStream();
+		virtual void startInternetStream(const char* url);
+		virtual void stopInternetStream();
+		virtual void updateInternetStream();
+		virtual void pauseInternetStream(int pause);
+		virtual int isInternetStreamPlaying();
+		virtual void getInternetStreamInfo(char* artist, char* title);
+		virtual void setInternetStreamGain(F32 vol);
+		virtual const char* getInternetStreamURL();
+
+		void initWind();
+		void cleanupWind();
+		void updateWind(LLVector3, F32);
+
+	protected:
+		char mInternetStreamURL[MAX_SIZE_STREAM_URL];	/*Flawfinder: ignore*/
+
+	private:
+		LLMediaImplGStreamer * m_streamer;
+		void * windDSP(void *newbuffer, int length);
+
+};
+
+class LLAudioChannelOpenAL : public LLAudioChannel{
+	public:
+		LLAudioChannelOpenAL();
+		virtual ~LLAudioChannelOpenAL();
+	protected:
+		void play();
+		void playSynced(LLAudioChannel *channelp);
+		void cleanup();
+		BOOL isPlaying();
+
+		BOOL updateBuffer();
+		void update3DPosition();
+		void updateLoop(){};
+
+		ALuint ALSource;
+};
+
+class LLAudioBufferOpenAL : public LLAudioBuffer{
+	public:
+		LLAudioBufferOpenAL();
+		virtual ~LLAudioBufferOpenAL();
+
+		BOOL loadWAV(const char *filename);
+		U32 getLength();
+
+		friend class LLAudioChannelOpenAL;
+	protected:
+		void cleanup();
+		ALuint getBuffer(){return ALBuffer;}
+		ALuint ALBuffer;
+};
+
+#endif
+
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/files.lst ./indra/llaudio/files.lst
--- ./indra/llaudio/files.lst	2007-12-21 22:03:17.000000000 +0000
+++ ./indra/llaudio/files.lst	2008-01-06 21:41:07.000000000 +0000
@@ -1,7 +1,7 @@
 llaudio/audioengine.cpp
-llaudio/audioengine_fmod.cpp
+llaudio/audioengine_openal.cpp
 llaudio/listener.cpp
-llaudio/listener_fmod.cpp
+llaudio/listener_openal.cpp
 llaudio/llaudiodecodemgr.cpp
 llaudio/vorbisdecode.cpp
 llaudio/vorbisencode.cpp
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/listener_dummy.cpp ./indra/llaudio/listener_dummy.cpp
--- ./indra/llaudio/listener_dummy.cpp	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/listener_dummy.cpp	2008-01-06 21:41:07.000000000 +0000
@@ -0,0 +1,31 @@
+#include "linden_common.h"
+#include "audioengine.h"
+
+#include "listener_dummy.h"
+
+LLListener_DUMMY::LLListener_DUMMY(){
+	init();
+}
+
+LLListener_DUMMY::~LLListener_DUMMY(){
+}
+
+void LLListener_DUMMY::translate(LLVector3 offset){
+	LLListener::translate(offset);
+	//llinfos << "LLListener_DUMMY::transelate() : " << offset << llendl;
+}
+
+void LLListener_DUMMY::setPosition(LLVector3 pos){
+	LLListener::setPosition(pos);
+	//llinfos << "LLListener_DUMMY::setPosition() : " << pos << llendl;
+}
+
+void LLListener_DUMMY::setVelocity(LLVector3 vel){
+	LLListener::setVelocity(vel);
+	//llinfos << "LLListener_DUMMY::setVelocity() : " << vel << llendl;
+}
+
+void LLListener_DUMMY::orient(LLVector3 up, LLVector3 at){
+	LLListener::orient(up, at);
+	//llinfos << "LLListener_DUMMY::orient() up: " << up << " at: " << at << llendl;
+}
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/listener_dummy.h ./indra/llaudio/listener_dummy.h
--- ./indra/llaudio/listener_dummy.h	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/listener_dummy.h	2008-01-06 21:41:07.000000000 +0000
@@ -0,0 +1,20 @@
+#ifndef LL_LISTENER_DUMMY_H
+#define LL_LISTENER_DUMMY_H
+
+#include "listener.h"
+
+class LLListener_DUMMY : public LLListener
+{
+ private:
+	
+ public:  
+	LLListener_DUMMY();
+	virtual ~LLListener_DUMMY();
+
+	virtual void translate(LLVector3 offset);
+	virtual void setPosition(LLVector3 pos);
+	virtual void setVelocity(LLVector3 vel);
+	virtual void orient(LLVector3 up, LLVector3 at);
+};
+
+#endif
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/listener_openal.cpp ./indra/llaudio/listener_openal.cpp
--- ./indra/llaudio/listener_openal.cpp	1970-01-01 01:00:00.000000000 +0100
+++ ./indra/llaudio/listener_openal.cpp	2008-01-08 15:18:40.000000000 +0000
@@ -0,0 +1,70 @@
+
+#include "linden_common.h"
+#include "audioengine.h"
+
+#if LL_OPENAL
+
+#include "listener_openal.h"
+
+LLListener_OpenAL::LLListener_OpenAL(){
+	init();
+}
+
+LLListener_OpenAL::~LLListener_OpenAL(){
+}
+
+void LLListener_OpenAL::translate(LLVector3 offset){
+	LLListener::translate(offset);
+	llinfos << "LLListener_OpenAL::transelate() : " << offset << llendl;
+}
+
+void LLListener_OpenAL::setPosition(LLVector3 pos){
+	LLListener::setPosition(pos);
+	//llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl;
+}
+
+void LLListener_OpenAL::setVelocity(LLVector3 vel){
+	LLListener::setVelocity(vel);
+}
+
+void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at){
+	LLListener::orient(up, at);
+	//llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl;
+}
+
+void LLListener_OpenAL::commitDeferredChanges(){
+	ALfloat orientation[6];
+	orientation[0] = mListenAt.mV[0];
+	orientation[1] = mListenAt.mV[1];
+	orientation[2] = mListenAt.mV[2];
+	orientation[3] = mListenUp.mV[0];
+	orientation[4] = mListenUp.mV[1];
+	orientation[5] = mListenUp.mV[2];
+
+	// Why is this backwards?
+	ALfloat velocity[3];
+	velocity[0] = -mVelocity.mV[0];
+	velocity[1] = -mVelocity.mV[1];
+	velocity[2] = -mVelocity.mV[2];
+
+	alListenerfv(AL_ORIENTATION, orientation);
+	alListenerfv(AL_POSITION, mPosition.mV);
+	alListenerfv(AL_VELOCITY, velocity);
+}
+
+void LLListener_OpenAL::setDopplerFactor(F32 factor){
+	// Effect is way too strong by default, scale it down here.
+	// Scaling the speed of sound up causes crashes.
+	factor *= 0.01f;
+	//llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
+	alDopplerFactor(factor);
+}
+
+F32 LLListener_OpenAL::getDopplerFactor(){
+	ALfloat factor=0.0f;
+	alDopplerFactor(factor);
+	//llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
+	return factor;
+}
+
+#endif
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/listener_openal.h ./indra/llaudio/listener_openal.h
--- ./indra/llaudio/listener_openal.h	2007-12-21 22:03:17.000000000 +0000
+++ ./indra/llaudio/listener_openal.h	2008-01-09 13:23:32.000000000 +0000
@@ -30,6 +30,7 @@
  * $/LicenseInfo$
  */
 
+
 #ifndef LL_LISTENER_OPENAL_H
 #define LL_LISTENER_OPENAL_H
 
@@ -54,7 +55,10 @@
 	virtual void setPosition(LLVector3 pos);
 	virtual void setVelocity(LLVector3 vel);
 	virtual void orient(LLVector3 up, LLVector3 at);
+	virtual void commitDeferredChanges();
+
+	virtual void setDopplerFactor(F32 factor);
+	virtual F32 getDopplerFactor();
 };
 
 #endif
-
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/llaudio/llaudiodecodemgr.cpp ./indra/llaudio/llaudiodecodemgr.cpp
--- ./indra/llaudio/llaudiodecodemgr.cpp	2007-12-21 22:03:17.000000000 +0000
+++ ./indra/llaudio/llaudiodecodemgr.cpp	2008-01-06 21:41:07.000000000 +0000
@@ -374,16 +374,15 @@
   
 		// write "data" chunk length, in little-endian format
 		S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
-		mWAVBuffer[40] = (data_length) & 0x000000FF;
-		mWAVBuffer[41] = (data_length >> 8) & 0x000000FF;
-		mWAVBuffer[42] = (data_length >> 16) & 0x000000FF;
-		mWAVBuffer[43] = (data_length >> 24) & 0x000000FF;
+		mWAVBuffer[40] = (data_length - 8) & 0x000000FF;
+		mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF;
+		mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF;
+		mWAVBuffer[43] = ((data_length - 8)>> 24) & 0x000000FF;
 		// write overall "RIFF" length, in little-endian format
-		data_length += 36;
-		mWAVBuffer[4] = (data_length) & 0x000000FF;
-		mWAVBuffer[5] = (data_length >> 8) & 0x000000FF;
-		mWAVBuffer[6] = (data_length >> 16) & 0x000000FF;
-		mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
+		mWAVBuffer[4] = (data_length + 28) & 0x000000FF;
+		mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF;
+		mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF;
+		mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF;
 
 		//
 		// FUCK!!! Vorbis encode/decode messes up loop point transitions (pop)
@@ -395,7 +394,7 @@
 			S32 fade_length;
 			char pcmout[4096];		/*Flawfinder: ignore*/ 	
 
-			fade_length = llmin((S32)128,(S32)(data_length-36)/8);			
+			fade_length = llmin((S32)128,(S32)(data_length)/8);			
 			if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
 			{
 				memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length));	/*Flawfinder: ignore*/
@@ -435,7 +434,7 @@
 			}
 		}
 
-		if (36 == data_length)
+		if (0 == data_length)
 		{
 			llwarns << "BAD Vorbis decode in finishDecode!" << llendl;
 			mValid = FALSE;
@@ -443,7 +442,7 @@
 		}
 #if !defined(USE_WAV_VFILE)
 		mBytesRead = -1;
-		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length,
+		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length + 36,
 												 new WriteResponder(this));
 #endif
 	}
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/newview/llappviewer.cpp ./indra/newview/llappviewer.cpp
--- ./indra/newview/llappviewer.cpp	2007-12-21 22:03:36.000000000 +0000
+++ ./indra/newview/llappviewer.cpp	2008-01-10 09:15:40.000000000 +0000
@@ -1581,17 +1581,10 @@
 
 	llinfos << "Global stuff deleted" << llendflush;
 
-#if !LL_RELEASE_FOR_DOWNLOAD
 	if (gAudiop)
 	{
 		gAudiop->shutdown();
 	}
-#else
-	// This hack exists because fmod likes to occasionally hang forever
-	// when shutting down for no apparent reason.
-	llwarns << "Hack, skipping audio engine cleanup" << llendflush;
-#endif
-
 
 	// moved to main application shutdown for now because it's non-trivial and only needs to be done once
 	// (even though it goes against the media framework design)
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/newview/llstartup.cpp ./indra/newview/llstartup.cpp
--- ./indra/newview/llstartup.cpp	2007-12-21 22:03:37.000000000 +0000
+++ ./indra/newview/llstartup.cpp	2008-01-10 09:15:38.000000000 +0000
@@ -41,10 +41,15 @@
 
 #include "audioengine.h"
 
+ 
 #if LL_FMOD
 #include "audioengine_fmod.h"
 #endif
 
+#if LL_OPENAL
+#include "audioengine_openal.h"
+#endif
+
 #include "audiosettings.h"
 #include "llares.h"
 #include "llcachename.h"
@@ -603,14 +608,26 @@
 		// or audio cues in connection UI.
 		//-------------------------------------------------
 
+// Audio engines FMOD and OpenAL are selectable at build time. If both are enabled then if FMOD fails OpenAL
+// will be attempted next. FMOD can be disabled by setting the LL_BAD_ALSA/OSS/ESD environmental variables.
+// OpenAL can be prevented from loading with LL_BAD_OPENAL.
+
 		if (gUseAudio)
 		{
+			gAudiop = NULL;
 #if LL_FMOD
 			gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
-#else
-			gAudiop = NULL;
 #endif
 
+#if LL_OPENAL
+
+			// FMOD not compiled or run time detected, try OpenAL
+			if(gAudiop==NULL)
+			{
+				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
+			}
+#endif	
+
 			if (gAudiop)
 			{
 #if LL_WINDOWS
diff -urN -x.svn -xdebian/ -x.rej -x'*~' ./indra/SConstruct ./indra/SConstruct
--- ./indra/SConstruct	2007-12-21 22:03:16.000000000 +0000
+++ ./indra/SConstruct	2008-01-10 09:15:40.000000000 +0000
@@ -96,7 +96,8 @@
         allowed_values=('Release', 'Release Candidate', 'WindLight')),
     BoolOption('ELFIO', 'Enabled enhanced backtraces with libELFIO symbol extraction support', True),
     BoolOption('STANDALONE', 'Build using system packages (implies OPENSOURCE)', False),
-    BoolOption('OPENSOURCE', 'Build using only non-proprietary dependencies', True) # OPENSOURCE: do not edit this line
+    BoolOption('OPENSOURCE', 'Build using only non-proprietary dependencies', True), # OPENSOURCE: do not edit this line
+    BoolOption('OPENAL', 'Build using OpenAL Audio support', True)
 )
 optenv = Environment(options = opts)
 Help(opts.GenerateHelpText(optenv))
@@ -114,6 +115,7 @@
 opensource = standalone or optenv['OPENSOURCE']
 enable_fmod = not opensource and optenv['FMOD']
 elfio = optenv['ELFIO']
+enable_openal = opensource or optenv['OPENAL']
 
 targets = [ target_param ]
 
@@ -155,6 +157,13 @@
     'libssl',
     ]
 
+if enable_gstreamer:
+    standalone_pkgs.append( 'gstreamer-0.10' )
+
+if enable_openal:
+    standalone_pkgs.append( 'openal' )
+    standalone_pkgs.append( 'freealut' )
+
 def pkgconfig(opt, pkgs=None):
     if pkgs is None:
         pkgs = standalone_pkgs + standalone_net_pkgs
@@ -249,6 +254,10 @@
     if standalone:
         cppflags += '-DLL_STANDALONE '
 
+    if enable_openal:
+    	cppflags += ' -DLL_OPENAL '
+
+
     if build_target == 'server':
         # Server flags
         cppflags += '-D_GNU_SOURCE -DLL_MESA_HEADLESS=1 -DLL_MESA=1 '
