Index: audioengine.cpp
===================================================================
--- audioengine.cpp	(revision 591)
+++ audioengine.cpp	(working copy)
@@ -1336,7 +1336,11 @@
 BOOL LLAudioSource::isDone()
 {
 	const F32 MAX_AGE = 60.f;
+#if LL_OPENAL
+	const F32 MAX_UNPLAYED_AGE = 30.f;
+#else
 	const F32 MAX_UNPLAYED_AGE = 15.f;
+#endif
 	if (isLoop())
 	{
 		// Looped sources never die on their own.
Index: audioengine.h
===================================================================
--- audioengine.h	(revision 591)
+++ audioengine.h	(working copy)
@@ -144,6 +144,9 @@
 	// use a value from 0.0 to 1.0, inclusive
 	virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; }
 	virtual const char* getInternetStreamURL() { return ""; }
+#if LL_OPENAL
+	virtual void InitStreamer() = 0;
+#endif
 
 	// For debugging usage
 	virtual LLVector3 getListenerPos();
Index: audioengine_openal.cpp
===================================================================
--- audioengine_openal.cpp	(revision 0)
+++ audioengine_openal.cpp	(revision 0)
@@ -0,0 +1,622 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ * Copyright (c) 2002-2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ */
+
+#include "linden_common.h"
+
+#if LL_OPENAL
+
+#include "audioengine_openal.h"
+#include "listener_openal.h"
+
+#if LL_OPENAL_WIND
+// Variables and definitions for Wind
+#define NO_WIND_BUFFERS 20
+static ALuint wind_buffers[NO_WIND_BUFFERS];
+static ALuint wind_sources[1];
+static S16 *winddata=NULL;
+
+static BOOL first_wind=TRUE;
+
+ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
+
+// 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;
+#endif // LL_OPENAL_WIND
+
+LLAudioEngine_OpenAL::LLAudioEngine_OpenAL(){
+
+#if LL_GSTREAMER_ENABLED
+	mMedia_data = new LLMediaManagerData;
+	LLMediaImplGStreamer::startup( mMedia_data );	// initialize GStreamer
+
+	m_streamer=new LLMediaImplGStreamer ();
+
+	if(!m_streamer)
+	{
+		llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
+	}
+#endif
+}
+
+LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL(){
+}
+
+BOOL LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata){
+	LLAudioEngine::init(num_channels, userdata);
+
+	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);
+#if LL_GSTREAMER_ENABLED
+       if(m_streamer != NULL)
+		m_streamer->updateMedia();
+#endif
+}
+
+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;
+
+#if LL_GSTREAMER_ENABLED
+	if(m_streamer){
+		delete m_streamer;
+		m_streamer = NULL;
+	}
+#endif
+}
+
+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::initWind(){
+#if LL_OPENAL_WIND
+	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*2*2); //200ms @44100Hz Stereo
+
+       if(winddata==NULL)
+       {
+               llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
+               mEnableWind=FALSE;
+       }
+
+       llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
+#endif
+}
+
+void LLAudioEngine_OpenAL::cleanupWind(){
+#if LL_OPENAL_WIND
+       llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
+
+       alDeleteBuffers(NO_WIND_BUFFERS,wind_buffers);
+
+       alDeleteSources(1, wind_sources);
+
+       if(winddata)
+               free(winddata);
+#endif
+}
+
+void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude){
+#if LL_OPENAL_WIND
+       LLVector3 wind_pos;
+       F64 pitch;
+       F64 center_freq;
+       ALenum error;
+
+       mMaxWindGain=1.0;
+
+       if (!mEnableWind)
+               return;
+
+       if(!winddata)
+               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);
+
+               ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]};
+
+               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<NO_WIND_BUFFERS;counter++)
+               {
+                       alBufferData(wind_buffers[counter],AL_FORMAT_STEREO16,windDSP((void*)winddata,2*44100*0.02),2*44100*0.02*sizeof(U16),44100);
+                       if((error=alGetError()) != AL_NO_ERROR)
+                       {
+                               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating INITAL WIND BUFFER 1: "<<error<<llendl;
+                       }
+               }
+
+               alSourceQueueBuffers(wind_sources[0], NO_WIND_BUFFERS, wind_buffers);
+
+               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;
+
+
+               }
+
+               int playing;
+               alGetSourcei(wind_sources[0], AL_SOURCE_STATE, &playing);
+
+               if(playing==AL_STOPPED)
+                       alSourcePlay(wind_sources[0]);
+
+       }
+#endif //LL_OPENAL_WIND
+}
+
+inline S16 clipSample(S16 sample, S16 min, S16 max)
+{
+#if LL_OPENAL_WIND
+       if (sample > max)
+               sample = max;
+       else if (sample < min)
+               sample = min;
+
+#endif
+       return sample;
+}
+
+void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length)
+{
+#if LL_OPENAL_WIND
+       // newbuffer = the buffer passed from the previous DSP unit.
+       // length = length in samples at this mix time.
+
+       U8 *cursamplep = (U8*)newbuffer;
+       U8   wordsize = 2;
+
+       double bandwidth = 50;
+       double inputSamplingRate = 44100;
+       double a0,b1,b2;
+
+       // 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;
+
+               S16     sample;
+
+               sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
+               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
+
+               cursamplep += wordsize;
+
+               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
+
+               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
+               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
+               cursamplep += wordsize;
+       }
+
+       return newbuffer;
+#endif //LL_OPENAL_WIND
+}
+
+// ------------
+
+void LLAudioEngine_OpenAL::InitStreamer()
+{
+#if LL_GSTREAMER_ENABLED
+       m_streamer=new LLMediaImplGStreamer ();
+
+       if(!m_streamer)
+       {
+               llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
+       }
+
+       if(m_streamer)
+       {
+               m_streamer->init ();
+       }
+#endif
+}
+
+// ------------
+
+void LLAudioEngine_OpenAL::initInternetStream(){
+	if(!mInternetStreamURL.empty())
+		mInternetStreamURL.erase();
+}
+
+void LLAudioEngine_OpenAL::startInternetStream(const char * url_cstr){
+
+	std::string url(url_cstr);
+
+#if LL_GSTREAMER_ENABLED
+	if(!m_streamer)
+		return;
+// DCF_DEBUG
+llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl;
+	
+
+	if (!url.empty()) {
+		llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl;
+		mInternetStreamURL=url;
+		m_streamer->navigateTo ( url );
+		llinfos << "Playing....." << llendl;		
+		m_streamer->addCommand(LLMediaBase::COMMAND_START);
+		m_streamer->updateMedia();
+
+	}else{
+		llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl;
+		mInternetStreamURL.erase();
+		m_streamer->addCommand(LLMediaBase::COMMAND_STOP);
+		m_streamer->updateMedia();
+	}
+#endif
+}
+
+void LLAudioEngine_OpenAL::updateInternetStream(){
+// DCF_DEBUG
+llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl;
+	
+}
+
+void LLAudioEngine_OpenAL::stopInternetStream(){
+// DCF_DEBUG
+llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl;
+	
+#if LL_GSTREAMER_ENABLED
+	if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)){
+		llinfos << "attempting to stop stream failed!" << llendl;
+	}
+	m_streamer->updateMedia();
+#endif
+	mInternetStreamURL.erase();
+}
+
+void LLAudioEngine_OpenAL::pauseInternetStream(int pause){
+#if LL_GSTREAMER_ENABLED
+	if(!m_streamer)
+		return;
+// DCF_DEBUG
+llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl;
+	
+	if(pause){
+		if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)){
+			llinfos << "attempting to pause stream failed!" << llendl;
+		}
+		m_streamer->updateMedia();
+	}else{
+		if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)){
+			llinfos << "attempting to pause stream failed!" << llendl;
+		}
+		m_streamer->updateMedia();
+	}
+#endif
+}
+
+int LLAudioEngine_OpenAL::isInternetStreamPlaying(){
+
+#if LL_GSTREAMER_ENABLED
+	if(!m_streamer)
+		return 0;
+	
+	if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED)
+	{
+		return 1; // Active and playing
+	}	
+
+	if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED)
+	{
+		return 2; // paused
+	}
+
+	return 0; // Stopped
+#endif
+}
+
+void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out){
+}
+
+void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol){
+#if LL_GSTREAMER_ENABLED
+	// Set the gstreamer volume here
+	if(!m_streamer)
+		return;
+
+	vol = llclamp(vol, 0.f, 1.f);
+	m_streamer->setVolume(vol);
+	m_streamer->updateMedia();
+
+#endif
+}
+
+const char* LLAudioEngine_OpenAL::getInternetStreamURL(){
+	return mInternetStreamURL.c_str();
+}
+
+#endif
Index: audioengine_openal.h
===================================================================
--- audioengine_openal.h	(revision 0)
+++ audioengine_openal.h	(revision 0)
@@ -0,0 +1,118 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ * Copyright (c) 2002-2008, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ */
+
+#if LL_OPENAL
+
+#ifndef LL_AUDIOENGINE_OpenAL_H
+#define LL_AUDIOENGINE_OpenAL_H
+
+#include <string>
+
+#include "audioengine.h"
+#include "listener_openal.h"
+#include "llmediamanager.h"
+#include "llmediaimplgstreamer.h"
+#include "llrand.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_cstr);
+		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();
+		virtual void InitStreamer();
+
+		void initWind();
+		void cleanupWind();
+		void updateWind(LLVector3 direction, F32 camera_altitude);
+
+	protected:
+		std::string mInternetStreamURL;
+		void * windDSP(void *newbuffer, int length);
+#if LL_GSTREAMER_ENABLED
+		LLMediaManagerData * mMedia_data;
+		LLMediaImplGStreamer * m_streamer;
+#endif
+};
+
+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
+#endif
Index: files.lst
===================================================================
--- files.lst	(revision 591)
+++ files.lst	(working copy)
@@ -1,7 +1,9 @@
 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
Index: listener_openal.cpp
===================================================================
--- listener_openal.cpp	(revision 0)
+++ listener_openal.cpp	(revision 0)
@@ -0,0 +1,97 @@
+/**
+ * @file audioengine_openal.cpp
+ * @brief implementation of audio engine using OpenAL
+ * support as a OpenAL 3D implementation
+ *
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ */
+
+#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::translate() : " << 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;
+	alDopplerFactor(factor);
+	llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
+	return factor;
+}
+#endif
Index: listener_openal.h
===================================================================
--- listener_openal.h	(revision 591)
+++ listener_openal.h	(working copy)
@@ -35,6 +35,8 @@
 
 #include "listener.h"
 
+#if LL_OPENAL
+
 #include "AL/al.h"
 #include "AL/alut.h"
 
@@ -54,7 +56,11 @@
 	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
-
+#endif
Index: llaudiodecodemgr.cpp
===================================================================
--- llaudiodecodemgr.cpp	(revision 591)
+++ llaudiodecodemgr.cpp	(working copy)
@@ -374,19 +374,34 @@
   
 		// write "data" chunk length, in little-endian format
 		S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
+#if LL_OPENAL
+		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;
+#else
 		mWAVBuffer[40] = (data_length) & 0x000000FF;
 		mWAVBuffer[41] = (data_length >> 8) & 0x000000FF;
 		mWAVBuffer[42] = (data_length >> 16) & 0x000000FF;
 		mWAVBuffer[43] = (data_length >> 24) & 0x000000FF;
+#endif
+
 		// write overall "RIFF" length, in little-endian format
+#if LL_OPENAL
+		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;
+#else
 		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;
+#endif
 
 		//
-		// FUCK!!! Vorbis encode/decode messes up loop point transitions (pop)
+		// Vorbis encode/decode messes up loop point transitions (pop)
 		// do a cheap-and-cheesy crossfade 
 		//
 		{
@@ -395,7 +410,11 @@
 			S32 fade_length;
 			char pcmout[4096];		/*Flawfinder: ignore*/ 	
 
+#if LL_OPENAL
+			fade_length = llmin((S32)128,(S32)(data_length)/8);			
+#else
 			fade_length = llmin((S32)128,(S32)(data_length-36)/8);			
+#endif
 			if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
 			{
 				memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length));	/*Flawfinder: ignore*/
@@ -435,7 +454,11 @@
 			}
 		}
 
+#if LL_OPENAL
+		if (0 == data_length)
+#else
 		if (36 == data_length)
+#endif
 		{
 			llwarns << "BAD Vorbis decode in finishDecode!" << llendl;
 			mValid = FALSE;
@@ -443,9 +466,14 @@
 		}
 #if !defined(USE_WAV_VFILE)
 		mBytesRead = -1;
+#if LL_OPENAL
+		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length + 36,
+												 new WriteResponder(this));
+#else
 		mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length,
 												 new WriteResponder(this));
 #endif
+#endif
 	}
 
 	if (mFileHandle != LLLFSThread::nullHandle())
