Browse Source

Fixed alxPause/unPause functions, which previously deleted sources upon Pausing.
Special thanks to Richard Ranft for submitting 99% of these changes

capnlove 12 years ago
parent
commit
79a8e6d6af

+ 74 - 27
engine/source/audio/audio.cc

@@ -102,6 +102,7 @@ struct LoopingImage
 static F32 mMasterVolume = 1.f;           // traped from AL_LISTENER gain (miles has difficulties with 3d sources)
 
 static ALuint                 mSource[MAX_AUDIOSOURCES];                   // ALSources
+static ALint                  mResumePosition[MAX_AUDIOSOURCES];           // Ensures Pause resumes from the correct position
 static AUDIOHANDLE            mHandle[MAX_AUDIOSOURCES];                   // unique handles
 static Resource<AudioBuffer>  mBuffer[MAX_AUDIOSOURCES];                   // each of the playing buffers (needed for AudioThread)
 static F32                    mScore[MAX_AUDIOSOURCES];                    // for figuring out which sources to cull/uncull
@@ -965,30 +966,17 @@ bool alxPause( AUDIOHANDLE handle )
 
     alSourcePause( mSource[index] );
 
-    ALenum error = 0;
-    if ( (error = alGetError()) == AL_NO_ERROR)
-        return true;
-    switch (error)
-    {
-        case AL_INVALID_NAME:
-            Con::errorf("alxPause - OpenAL AL_INVALID_NAME error code returned");
-            break;
-        case AL_INVALID_ENUM:
-            Con::errorf("alxPause - OpenAL AL_INVALID_ENUM error code returned");
-            break;
-        case AL_INVALID_VALUE:
-            Con::errorf("alxPause - OpenAL AL_INVALID_VALUE error code returned");
-            break;
-        case AL_INVALID_OPERATION:
-            Con::errorf("alxPause - OpenAL AL_INVALID_OPERATION error code returned");
-            break;
-        case AL_OUT_OF_MEMORY:
-            Con::errorf("alxPause - OpenAL AL_OUT_OF_MEMORY error code returned");
-            break;
-        default:
-            Con::errorf("alxPause - OpenAL has encountered a problem and won't tell us what it is.");
-    };
-    return false;
+    ALint state;
+	alGetSourcei(mSource[index], AL_SOURCE_STATE, &state);
+
+	if( state==AL_PAUSED)
+	{
+		mResumePosition[index] = -1;
+		return true;
+	}
+
+	alGetSourcei(mSource[index], AL_SAMPLE_OFFSET, &mResumePosition[index]);
+	return alxCheckError("alxPause()","alGetSourcei");
 }
 
 void alxUnPause( AUDIOHANDLE handle )
@@ -996,7 +984,18 @@ void alxUnPause( AUDIOHANDLE handle )
     if(handle == NULL_AUDIOHANDLE)
         return;
     
-    alxPlay( handle );
+	U32 index = alxFindIndex(handle);
+	ALuint source = mSource[index];
+
+	if( mResumePosition[index] != -1 )
+	{
+		alSourcei( source, AL_SAMPLE_OFFSET, mResumePosition[index]);
+		mResumePosition[index] = -1;
+	}
+	alxCheckError("alxUnPause()","alSourcei");
+
+	alSourcePlay( source );
+	alxCheckError("alxUnPause()","alSourcePlay");
 }
 //--------------------------------------------------------------------------
 void alxStop(AUDIOHANDLE handle)
@@ -1920,7 +1919,7 @@ void alxCloseHandles()
 
       ALint state = 0;
       alGetSourcei(mSource[i], AL_SOURCE_STATE, &state);
-      if(state == AL_PLAYING)
+      if(state == AL_PLAYING || state == AL_PAUSED)
          continue;
 
       if(!(mHandle[i] & AUDIOHANDLE_INACTIVE_BIT))
@@ -1979,6 +1978,11 @@ void alxUpdateScores(bool sourcesOnly)
          continue;
       }
 
+	  ALint state = 0;
+	  alGetSourcei(mSource[i], AL_SOURCE_STATE, &state);
+	  if(state==AL_PAUSED)
+		  continue;
+
       // grab the volume.. (not attenuated by master for score)
       F32 volume = mSourceVolume[i] * mAudioChannelVolumes[mType[i]];
 
@@ -2159,6 +2163,36 @@ ALuint alxGetWaveLen(ALuint buffer)
    return(len);
 }
 
+bool alxCheckError(const char* sourceFuncName, const char* alFuncName)
+{
+  ALenum errorVal = alGetError();
+  switch (errorVal)
+  {
+    case AL_NO_ERROR:
+      break;
+    case AL_INVALID_NAME:
+      Con::errorf("%s - %s OpenAL AL_INVALID_NAME error code returned", sourceFuncName, alFuncName);
+      break;
+    case AL_INVALID_ENUM:
+      Con::errorf("%s - %s OpenAL AL_INVALID_ENUM error code returned", sourceFuncName, alFuncName);
+      break;
+    case AL_INVALID_VALUE:
+      Con::errorf("%s - %s OpenAL AL_INVALID_VALUE error code returned", sourceFuncName, alFuncName);
+      break;
+    case AL_INVALID_OPERATION:
+      Con::errorf("%s - %s OpenAL AL_INVALID_OPERATION error code returned", sourceFuncName, alFuncName);
+      break;
+    case AL_OUT_OF_MEMORY:
+      Con::errorf("%s - %s OpenAL AL_OUT_OF_MEMORY error code returned", sourceFuncName, alFuncName);
+      break;
+    default:
+      Con::errorf("%s - %s OpenAL has encountered a problem and won't tell us what it is. %d", errorVal, sourceFuncName, alFuncName);
+  };
+  if (errorVal == AL_NO_ERROR)
+    return true;
+  else
+    return false;
+}
 
 //--------------------------------------------------------------------------
 // Environment:
@@ -2531,9 +2565,22 @@ void OpenALShutdown()
       delete mLoopingFreeList.last();
       mLoopingFreeList.pop_back();
    }
+   
+   //clear error buffer
+   alGetError();
 
    for(U32 i = 0; i < MAX_AUDIOSOURCES; i++)
-      mBuffer[i] = 0;
+   {
+	   ALint tempbuff = 0;
+	   alGetSourcei( mSource[i], AL_BUFFER, &tempbuff);
+
+	   if (alIsBuffer(tempbuff) && tempbuff !=0)
+	   {
+		   ALuint buffer = tempbuff;
+		   alSourceUnqueueBuffers( mSource[i], 1, &buffer);
+		   alxCheckError("OpenALShutdown()","alSourceUnqueueBuffers");
+	   }
+   }
 
    alDeleteSources(mNumSources, mSource);
 

+ 2 - 0
engine/source/audio/audio.h

@@ -38,5 +38,7 @@
 //-Mat default sample rate, change as needed
 #define DEFAULT_SOUND_OUTPUT_RATE		44100
 
+bool alxCheckError(const char*, const char*);
+
 
 #endif  // _H_AUDIO_

+ 31 - 8
engine/source/audio/audioBuffer.cc

@@ -110,14 +110,37 @@ AudioBuffer::AudioBuffer(StringTableEntry filename)
 
 AudioBuffer::~AudioBuffer()
 {
-   if( malBuffer != 0 ) 
-   {
-     alGetError();
-     alDeleteBuffers( 1, &malBuffer );
-     ALenum error;
-     error = alGetError();
-     AssertWarn( error == AL_NO_ERROR, "AudioBuffer::~AudioBuffer() - failed to release buffer" );
-   }
+   if( alIsBuffer(malBuffer) )
+  {
+    alGetError();
+    alDeleteBuffers( 1, &malBuffer );
+
+    ALenum error;
+    error = alGetError();
+    AssertWarn( error == AL_NO_ERROR, "AudioBuffer::~AudioBuffer() - failed to release buffer" );
+    switch (error)
+    {
+      case AL_NO_ERROR:
+        break;
+      case AL_INVALID_NAME:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL AL_INVALID_NAME error code returned");
+        break;
+      case AL_INVALID_ENUM:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL AL_INVALID_ENUM error code returned");
+        break;
+      case AL_INVALID_VALUE:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL AL_INVALID_VALUE error code returned");
+        break;
+      case AL_INVALID_OPERATION:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL AL_INVALID_OPERATION error code returned");
+        break;
+      case AL_OUT_OF_MEMORY:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL AL_OUT_OF_MEMORY error code returned");
+        break;
+      default:
+        Con::errorf("AudioBuffer::~AudioBuffer() - alDeleteBuffers OpenAL has encountered a problem and won't tell us what it is. %d", error);
+    };
+  }
 }
 
 //--------------------------------------

+ 6 - 3
engine/source/audio/audioFunctions.cc

@@ -92,6 +92,9 @@ static ALenum getEnum(const char * name, U32 flags)
       { "AL_CONE_INNER_ANGLE",            AL_CONE_INNER_ANGLE,             (Source|Get|Set|Int) },
       { "AL_CONE_OUTER_ANGLE",            AL_CONE_OUTER_ANGLE,             (Source|Get|Set|Int) },
       { "AL_LOOPING",                     AL_LOOPING,                      (Source|Get|Set|Int) },
+	  { "AL_SAMPLE_OFFSET",               AL_SAMPLE_OFFSET,                (Source|Get|Set|Int) },
+	  { "AL_SEC_OFFSET",                  AL_SEC_OFFSET,                   (Source|Get|Set|Int) },
+	  { "AL_BYTE_OFFSET",                 AL_BYTE_OFFSET,                  (Source|Get|Set|Int) },
       //{ "AL_STREAMING",                   AL_STREAMING,                    (Source|Get|Set|Int) },
       //{ "AL_BUFFER",                      AL_BUFFER,                       (Source|Get|Set|Int) },
 
@@ -342,7 +345,7 @@ ConsoleFunction(alxSourcei, void, 4, 4, "( handle , ALEnum , value ) Use the alx
       return;
    }
 
-   alxSourcei(dAtoi(argv[1]), e, dAtoi(argv[3]));
+   alxSourcei(dAtoi(argv[1]), e, static_cast<ALint>(dAtoi(argv[3])));
 }
 
 
@@ -406,9 +409,9 @@ ConsoleFunction(alxGetSourcei, S32, 3, 3, "( handle , ALEnum ) Use the alxGetSou
       return(0);
    }
 
-   S32 value;
+   ALint value;
    alxGetSourcei(dAtoi(argv[1]), e, &value);
-   return(value);
+   return(static_cast<S32>(value));
 }