Index: omvviewer-1.21.0/indra/llaudio/audioengine.cpp
===================================================================
--- omvviewer-1.21.0.orig/indra/llaudio/audioengine.cpp	2008-08-31 09:42:53.000000000 +0100
+++ omvviewer-1.21.0/indra/llaudio/audioengine.cpp	2008-08-31 14:26:27.000000000 +0100
@@ -111,6 +111,8 @@
 	// Initialize the decode manager
 	gAudioDecodeMgrp = new LLAudioDecodeMgr;
 
+	llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
+
 	return TRUE;
 }
 
@@ -1336,7 +1338,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: omvviewer-1.21.0/indra/llaudio/audioengine.h
===================================================================
--- omvviewer-1.21.0.orig/indra/llaudio/audioengine.h	2008-08-31 09:42:53.000000000 +0100
+++ omvviewer-1.21.0/indra/llaudio/audioengine.h	2008-08-31 11:54:11.000000000 +0100
@@ -159,6 +159,10 @@
 	static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
 
 
+	#if LL_OPENAL
+		virtual void InitStreamer() = 0;
+	#endif
+
 	friend class LLPipeline; // For debugging
 public:
 	F32 mMaxWindGain; // Hack.  Public to set before fade in?
Index: omvviewer-1.21.0/indra/llaudio/audioengine_openal.cpp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ omvviewer-1.21.0/indra/llaudio/audioengine_openal.cpp	2008-08-31 14:34:11.000000000 +0100
@@ -0,0 +1,618 @@
+/**
+ * @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"
+
+#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 std::string& filename){
+	cleanup();
+	ALBuffer = alutCreateBufferFromFile(filename.c_str());
+	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;
+       }
+
+#endif //LL_OPENAL_WIND
+       return newbuffer;
+}
+
+// ------------
+
+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 std::string& url){
+
+#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
+	}
+#endif
+	return 0; // Stopped
+}
+
+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 std::string& LLAudioEngine_OpenAL::getInternetStreamURL(){
+	return mInternetStreamURL;
+}
+
Index: omvviewer-1.21.0/indra/llaudio/audioengine_openal.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ omvviewer-1.21.0/indra/llaudio/audioengine_openal.h	2008-08-31 14:48:25.000000000 +0100
@@ -0,0 +1,122 @@
+/**
+ * @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.
+ */
+
+
+#ifndef LL_AUDIOENGINE_OpenAL_H
+#define LL_AUDIOENGINE_OpenAL_H
+
+
+#include <string>
+
+#include "audioengine.h"
+#include "listener_openal.h"
+
+
+#if LL_GSTREAMER_ENABLED
+#include "llmediamanager.h"
+#include "llmediaimplgstreamer.h"
+#endif
+
+#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 std::string& 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 std::string& 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 std::string& filename);
+		U32 getLength();
+
+		friend class LLAudioChannelOpenAL;
+	protected:
+		void cleanup();
+		ALuint getBuffer(){return ALBuffer;}
+		ALuint ALBuffer;
+};
+
+#endif
Index: omvviewer-1.21.0/indra/llaudio/listener_openal.cpp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ omvviewer-1.21.0/indra/llaudio/listener_openal.cpp	2008-08-31 13:53:08.000000000 +0100
@@ -0,0 +1,95 @@
+/**
+ * @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"
+
+#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;
+}
+
Index: omvviewer-1.21.0/indra/llaudio/listener_openal.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ omvviewer-1.21.0/indra/llaudio/listener_openal.h	2008-08-31 14:34:35.000000000 +0100
@@ -0,0 +1,62 @@
+/** 
+ * @file listener_openal.h
+ * @brief Description of LISTENER class abstracting the audio support
+ * as an OpenAL implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ * 
+ * Copyright (c) 2000-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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LISTENER_OPENAL_H
+#define LL_LISTENER_OPENAL_H
+
+#include "listener.h"
+#include "AL/al.h"
+#include "AL/alut.h"
+
+class LLListener_OpenAL  : public LLListener
+{
+ private:
+ protected:
+ public:
+
+ private:
+ protected:
+ public:  
+	LLListener_OpenAL();
+	virtual ~LLListener_OpenAL();
+
+	virtual void translate(LLVector3 offset);
+	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
Index: omvviewer-1.21.0/indra/llaudio/CMakeLists.txt
===================================================================
--- omvviewer-1.21.0.orig/indra/llaudio/CMakeLists.txt	2008-08-31 09:42:53.000000000 +0100
+++ omvviewer-1.21.0/indra/llaudio/CMakeLists.txt	2008-08-31 14:55:11.000000000 +0100
@@ -9,6 +9,7 @@
 include(LLMath)
 include(LLMessage)
 include(LLVFS)
+include(LLMedia)
 
 include_directories(
     ${FMOD_INCLUDE_DIR}
@@ -20,6 +21,10 @@
     ${VORBISENC_INCLUDE_DIRS}
     ${VORBISFILE_INCLUDE_DIRS}
     ${VORBIS_INCLUDE_DIRS}
+    ${OPENAL_LIB_INCLUDE_DIRS}
+    ${FREEAULT_LIB_INCLUDE_DIRS}
+    ${LLMEDIA_INCLUDE_DIRS}
+    ${GSTREAMER_INCLUDE_DIRS}
     )
 
 set(llaudio_SOURCE_FILES
@@ -59,6 +64,19 @@
     endif (LINUX)
 endif (FMOD)
 
+if (OPENAL)
+	list(APPEND llaudio_SOURCE_FILES
+	audioengine_openal.cpp
+	listener_openal.cpp
+	)
+
+	list(APPEND llaudio_HEADER_FILES
+	audioengine_openal.h
+	listener_openal.h
+	)
+  	
+endif (OPENAL)
+
 set_source_files_properties(${llaudio_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
Index: omvviewer-1.21.0/indra/newview/CMakeLists.txt
===================================================================
--- omvviewer-1.21.0.orig/indra/newview/CMakeLists.txt	2008-08-31 09:42:53.000000000 +0100
+++ omvviewer-1.21.0/indra/newview/CMakeLists.txt	2008-08-31 13:07:29.000000000 +0100
@@ -8,6 +8,7 @@
 include(DirectX)
 include(ELFIO)
 include(FMOD)
+include(OPENAL)
 include(FindOpenGL)
 include(LLAudio)
 include(LLCharacter)
@@ -56,6 +57,7 @@
     ${LLXML_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
+    ${GSTREAMER_INCLUDE_DIRS}
     )
 
 set(viewer_SOURCE_FILES
@@ -1240,6 +1242,11 @@
 
 #list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
 
+
+if (OPENAL)
+  set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_OPENAL)
+endif (OPENAL)
+
 if (FMOD)
   set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_FMOD)
 
Index: omvviewer-1.21.0/indra/cmake/OPENAL.cmake
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ omvviewer-1.21.0/indra/cmake/OPENAL.cmake	2008-08-31 13:09:59.000000000 +0100
@@ -0,0 +1,14 @@
+
+set(OPENAL OFF CACHE BOOL "Enable OpenAL")
+
+
+if (OPENAL)
+	include(FindPkgConfig)
+	pkg_check_modules(OPENAL_LIB REQUIRED openal)
+	pkg_check_modules(FREEAULT_LIB REQUIRED freealut)
+	set(OPENAL_LIBRARIES 
+		openal
+		alut
+	)
+		
+endif (OPENAL)
Index: omvviewer-1.21.0/indra/newview/llstartup.cpp
===================================================================
--- omvviewer-1.21.0.orig/indra/newview/llstartup.cpp	2008-08-31 09:42:53.000000000 +0100
+++ omvviewer-1.21.0/indra/newview/llstartup.cpp	2008-08-31 13:51:14.000000000 +0100
@@ -17,7 +17,7 @@
  * 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://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexceptionOP
  * 
  * By copying, modifying or distributing this software, you acknowledge
  * that you have read and understood your obligations described above,
@@ -45,6 +45,10 @@
 # include "audioengine_fmod.h"
 #endif
 
+#ifdef LL_OPENAL
+#include "audioengine_openal.h"
+#endif
+
 #include "llares.h"
 #include "llcachename.h"
 #include "llviewercontrol.h"
@@ -574,10 +578,14 @@
 
 		if (FALSE == gSavedSettings.getBOOL("NoAudio"))
 		{
+			gAudiop = NULL;
+
 #ifdef LL_FMOD
 			gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
-#else
-			gAudiop = NULL;
+#endif
+
+#ifdef LL_OPENAL
+			gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
 #endif
 
 			if (gAudiop)
Index: omvviewer-1.21.0/indra/cmake/LLAudio.cmake
===================================================================
--- omvviewer-1.21.0.orig/indra/cmake/LLAudio.cmake	2008-08-31 13:06:37.000000000 +0100
+++ omvviewer-1.21.0/indra/cmake/LLAudio.cmake	2008-08-31 13:07:05.000000000 +0100
@@ -8,6 +8,7 @@
 
 set(LLAUDIO_LIBRARIES
     llaudio
+    ${OPENAL_LIBRARIES}
     ${VORBISENC_LIBRARIES}
     ${VORBISFILE_LIBRARIES}
     ${VORBIS_LIBRARIES}
