/// <summary> /// Update this instance. /// </summary> void Update() { if (!audioSource) { return; } // If user called Play on the acutal AudioSource, account for this // NOTE: There may be a potential issue with calling AudioSource.Stop on a // looping sound, since the Update may not catch this. We might need to catch // this edge case at some point; a one-shot sound will stop automatically and // return spatialization resources. if ((isPlaying == false) && (audioSource.isPlaying)) { // This is a copy of OSPAudioSource Play function, minus // calling Play on audio source since it's already been called // Bail if manager has not even started if (OSPManager.IsInitialized() == false) { return; } // We will grab a context at this point, and set the right values // to allow for spatialization to take effect Aquire(); // We will set the relative position of this sound now before we start playing SetRelativeSoundPos(true); // We are ready to play the sound // Commented out, kept for readability // audioSource.Play(); lock (this) isPlaying = true; } // If sound is playing on it's own and dies off, we need to // Reset if (isPlaying == true) { // If we stopped the sound using AudioSource, Release resources if (audioSource.isPlaying == false) { lock (this) isPlaying = false; Release(); return; } // We will go back and forth between spatial processing // and native 2D panning if ((Bypass == true) || (OSPManager.GetBypass() == true)) { #if (!UNITY5) audioSource.spatialBlend = panLevel; #else audioSource.spatialBlend = panLevel; #endif audioSource.spread = spread; } else { // We want to remove FMod curve attenuation if we are doing our // own internal calc float pl = sSetPanLevel; if (OSPManager.GetUseInverseSquareAttenuation() == true) { pl = sSetPanLevelInvSq; } #if (!UNITY5) audioSource.spatialBlend = pl; #else audioSource.spatialBlend = pl; #endif audioSource.spread = sSetSpread; } // Update FrequencyHints and local reflection enable/disable if (context != sNoContext) { OSPManager.SetFrequencyHint(context, frequencyHint); OSPManager.SetDisableReflectionsOnSound(context, disableReflections); } // return the context when the sound has finished playing if ((audioSource.time >= audioSource.clip.length) && (audioSource.loop == false)) { // One last pass to allow for the tail portion of the sound // to finish drainTime = OSPManager.GetDrainTime(context); drain = true; } else { // We must set all positional properties here, not in // OnAudioFilterRead. We might consider a better approach // to interpolate the current location for better localization, // should the resolution of setting it here sound jittery due // to thread frequency mismatch. SetRelativeSoundPos(false); #if DEBUG_AudioSource // Time main thread and audio thread if (debugOn) { // Get audio frequency if (audioFrames == 0) { float ct = 1.0f / (GetTime(false) - dTimeMainLoop); Debug.LogWarning(System.String.Format("U: {0:F0}", ct)); ct = 100.0f / (GetTime(true) - PrevAudioTime); Debug.LogWarning(System.String.Format("A: {0:F0}", ct)); audioFrames = 100; PrevAudioTime = (float)GetTime(true); } dTimeMainLoop = (float)GetTime(false); } #endif } if (drain == true) { // Keep playing until we safely drain out the early reflections drainTime -= Time.deltaTime; if (drainTime < 0.0f) { drain = false; lock (this) isPlaying = false; // Stop will both stop audio from playing (keeping OnAudioFilterRead from // running with a held audio source) as well as release the spatialization // resources via Release() Stop(); } } } }